1846a86e2SMadalin Bucur /* Copyright 2008-2016 Freescale Semiconductor Inc. 2846a86e2SMadalin Bucur * 3846a86e2SMadalin Bucur * Redistribution and use in source and binary forms, with or without 4846a86e2SMadalin Bucur * modification, are permitted provided that the following conditions are met: 5846a86e2SMadalin Bucur * * Redistributions of source code must retain the above copyright 6846a86e2SMadalin Bucur * notice, this list of conditions and the following disclaimer. 7846a86e2SMadalin Bucur * * Redistributions in binary form must reproduce the above copyright 8846a86e2SMadalin Bucur * notice, this list of conditions and the following disclaimer in the 9846a86e2SMadalin Bucur * documentation and/or other materials provided with the distribution. 10846a86e2SMadalin Bucur * * Neither the name of Freescale Semiconductor nor the 11846a86e2SMadalin Bucur * names of its contributors may be used to endorse or promote products 12846a86e2SMadalin Bucur * derived from this software without specific prior written permission. 13846a86e2SMadalin Bucur * 14846a86e2SMadalin Bucur * 15846a86e2SMadalin Bucur * ALTERNATIVELY, this software may be distributed under the terms of the 16846a86e2SMadalin Bucur * GNU General Public License ("GPL") as published by the Free Software 17846a86e2SMadalin Bucur * Foundation, either version 2 of that License or (at your option) any 18846a86e2SMadalin Bucur * later version. 19846a86e2SMadalin Bucur * 20846a86e2SMadalin Bucur * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 21846a86e2SMadalin Bucur * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22846a86e2SMadalin Bucur * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23846a86e2SMadalin Bucur * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 24846a86e2SMadalin Bucur * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25846a86e2SMadalin Bucur * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26846a86e2SMadalin Bucur * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27846a86e2SMadalin Bucur * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28846a86e2SMadalin Bucur * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29846a86e2SMadalin Bucur * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30846a86e2SMadalin Bucur */ 31846a86e2SMadalin Bucur 32846a86e2SMadalin Bucur #include <linux/init.h> 33846a86e2SMadalin Bucur #include <linux/module.h> 34846a86e2SMadalin Bucur #include <linux/io.h> 35846a86e2SMadalin Bucur #include <linux/of_net.h> 36846a86e2SMadalin Bucur #include "dpaa_eth.h" 37846a86e2SMadalin Bucur #include "mac.h" 38846a86e2SMadalin Bucur 39846a86e2SMadalin Bucur static ssize_t dpaa_eth_show_addr(struct device *dev, 40846a86e2SMadalin Bucur struct device_attribute *attr, char *buf) 41846a86e2SMadalin Bucur { 42846a86e2SMadalin Bucur struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 43846a86e2SMadalin Bucur struct mac_device *mac_dev = priv->mac_dev; 44846a86e2SMadalin Bucur 45846a86e2SMadalin Bucur if (mac_dev) 46846a86e2SMadalin Bucur return sprintf(buf, "%llx", 47846a86e2SMadalin Bucur (unsigned long long)mac_dev->res->start); 48846a86e2SMadalin Bucur else 49846a86e2SMadalin Bucur return sprintf(buf, "none"); 50846a86e2SMadalin Bucur } 51846a86e2SMadalin Bucur 52846a86e2SMadalin Bucur static ssize_t dpaa_eth_show_fqids(struct device *dev, 53846a86e2SMadalin Bucur struct device_attribute *attr, char *buf) 54846a86e2SMadalin Bucur { 55846a86e2SMadalin Bucur struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 56846a86e2SMadalin Bucur struct dpaa_fq *prev = NULL; 57846a86e2SMadalin Bucur char *prevstr = NULL; 58846a86e2SMadalin Bucur struct dpaa_fq *tmp; 59846a86e2SMadalin Bucur struct dpaa_fq *fq; 60846a86e2SMadalin Bucur u32 first_fqid = 0; 61846a86e2SMadalin Bucur u32 last_fqid = 0; 62846a86e2SMadalin Bucur ssize_t bytes = 0; 63846a86e2SMadalin Bucur char *str; 64846a86e2SMadalin Bucur int i = 0; 65846a86e2SMadalin Bucur 66846a86e2SMadalin Bucur list_for_each_entry_safe(fq, tmp, &priv->dpaa_fq_list, list) { 67846a86e2SMadalin Bucur switch (fq->fq_type) { 68846a86e2SMadalin Bucur case FQ_TYPE_RX_DEFAULT: 69846a86e2SMadalin Bucur str = "Rx default"; 70846a86e2SMadalin Bucur break; 71846a86e2SMadalin Bucur case FQ_TYPE_RX_ERROR: 72846a86e2SMadalin Bucur str = "Rx error"; 73846a86e2SMadalin Bucur break; 74846a86e2SMadalin Bucur case FQ_TYPE_TX_CONFIRM: 75846a86e2SMadalin Bucur str = "Tx default confirmation"; 76846a86e2SMadalin Bucur break; 77846a86e2SMadalin Bucur case FQ_TYPE_TX_CONF_MQ: 78846a86e2SMadalin Bucur str = "Tx confirmation (mq)"; 79846a86e2SMadalin Bucur break; 80846a86e2SMadalin Bucur case FQ_TYPE_TX_ERROR: 81846a86e2SMadalin Bucur str = "Tx error"; 82846a86e2SMadalin Bucur break; 83846a86e2SMadalin Bucur case FQ_TYPE_TX: 84846a86e2SMadalin Bucur str = "Tx"; 85846a86e2SMadalin Bucur break; 86846a86e2SMadalin Bucur default: 87846a86e2SMadalin Bucur str = "Unknown"; 88846a86e2SMadalin Bucur } 89846a86e2SMadalin Bucur 90846a86e2SMadalin Bucur if (prev && (abs(fq->fqid - prev->fqid) != 1 || 91846a86e2SMadalin Bucur str != prevstr)) { 92846a86e2SMadalin Bucur if (last_fqid == first_fqid) 93846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, 94846a86e2SMadalin Bucur "%s: %d\n", prevstr, prev->fqid); 95846a86e2SMadalin Bucur else 96846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, 97846a86e2SMadalin Bucur "%s: %d - %d\n", prevstr, 98846a86e2SMadalin Bucur first_fqid, last_fqid); 99846a86e2SMadalin Bucur } 100846a86e2SMadalin Bucur 101846a86e2SMadalin Bucur if (prev && abs(fq->fqid - prev->fqid) == 1 && 102846a86e2SMadalin Bucur str == prevstr) { 103846a86e2SMadalin Bucur last_fqid = fq->fqid; 104846a86e2SMadalin Bucur } else { 105846a86e2SMadalin Bucur first_fqid = fq->fqid; 106846a86e2SMadalin Bucur last_fqid = fq->fqid; 107846a86e2SMadalin Bucur } 108846a86e2SMadalin Bucur 109846a86e2SMadalin Bucur prev = fq; 110846a86e2SMadalin Bucur prevstr = str; 111846a86e2SMadalin Bucur i++; 112846a86e2SMadalin Bucur } 113846a86e2SMadalin Bucur 114846a86e2SMadalin Bucur if (prev) { 115846a86e2SMadalin Bucur if (last_fqid == first_fqid) 116846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, "%s: %d\n", prevstr, 117846a86e2SMadalin Bucur prev->fqid); 118846a86e2SMadalin Bucur else 119846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr, 120846a86e2SMadalin Bucur first_fqid, last_fqid); 121846a86e2SMadalin Bucur } 122846a86e2SMadalin Bucur 123846a86e2SMadalin Bucur return bytes; 124846a86e2SMadalin Bucur } 125846a86e2SMadalin Bucur 126846a86e2SMadalin Bucur static ssize_t dpaa_eth_show_bpids(struct device *dev, 127846a86e2SMadalin Bucur struct device_attribute *attr, char *buf) 128846a86e2SMadalin Bucur { 129846a86e2SMadalin Bucur struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 130846a86e2SMadalin Bucur ssize_t bytes = 0; 131846a86e2SMadalin Bucur int i = 0; 132846a86e2SMadalin Bucur 133846a86e2SMadalin Bucur for (i = 0; i < DPAA_BPS_NUM; i++) 134846a86e2SMadalin Bucur bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", 135846a86e2SMadalin Bucur priv->dpaa_bps[i]->bpid); 136846a86e2SMadalin Bucur 137846a86e2SMadalin Bucur return bytes; 138846a86e2SMadalin Bucur } 139846a86e2SMadalin Bucur 140846a86e2SMadalin Bucur static struct device_attribute dpaa_eth_attrs[] = { 141846a86e2SMadalin Bucur __ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL), 142846a86e2SMadalin Bucur __ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL), 143846a86e2SMadalin Bucur __ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL), 144846a86e2SMadalin Bucur }; 145846a86e2SMadalin Bucur 146846a86e2SMadalin Bucur void dpaa_eth_sysfs_init(struct device *dev) 147846a86e2SMadalin Bucur { 148846a86e2SMadalin Bucur int i; 149846a86e2SMadalin Bucur 150846a86e2SMadalin Bucur for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 151846a86e2SMadalin Bucur if (device_create_file(dev, &dpaa_eth_attrs[i])) { 152846a86e2SMadalin Bucur dev_err(dev, "Error creating sysfs file\n"); 153846a86e2SMadalin Bucur while (i > 0) 154846a86e2SMadalin Bucur device_remove_file(dev, &dpaa_eth_attrs[--i]); 155846a86e2SMadalin Bucur return; 156846a86e2SMadalin Bucur } 157846a86e2SMadalin Bucur } 158846a86e2SMadalin Bucur 159846a86e2SMadalin Bucur void dpaa_eth_sysfs_remove(struct device *dev) 160846a86e2SMadalin Bucur { 161846a86e2SMadalin Bucur int i; 162846a86e2SMadalin Bucur 163846a86e2SMadalin Bucur for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 164846a86e2SMadalin Bucur device_remove_file(dev, &dpaa_eth_attrs[i]); 165846a86e2SMadalin Bucur } 166