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; 743150b7c2SMadalin Bucur case FQ_TYPE_RX_PCD: 753150b7c2SMadalin Bucur str = "Rx PCD"; 763150b7c2SMadalin Bucur break; 77846a86e2SMadalin Bucur case FQ_TYPE_TX_CONFIRM: 78846a86e2SMadalin Bucur str = "Tx default confirmation"; 79846a86e2SMadalin Bucur break; 80846a86e2SMadalin Bucur case FQ_TYPE_TX_CONF_MQ: 81846a86e2SMadalin Bucur str = "Tx confirmation (mq)"; 82846a86e2SMadalin Bucur break; 83846a86e2SMadalin Bucur case FQ_TYPE_TX_ERROR: 84846a86e2SMadalin Bucur str = "Tx error"; 85846a86e2SMadalin Bucur break; 86846a86e2SMadalin Bucur case FQ_TYPE_TX: 87846a86e2SMadalin Bucur str = "Tx"; 88846a86e2SMadalin Bucur break; 89846a86e2SMadalin Bucur default: 90846a86e2SMadalin Bucur str = "Unknown"; 91846a86e2SMadalin Bucur } 92846a86e2SMadalin Bucur 93846a86e2SMadalin Bucur if (prev && (abs(fq->fqid - prev->fqid) != 1 || 94846a86e2SMadalin Bucur str != prevstr)) { 95846a86e2SMadalin Bucur if (last_fqid == first_fqid) 96846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, 97846a86e2SMadalin Bucur "%s: %d\n", prevstr, prev->fqid); 98846a86e2SMadalin Bucur else 99846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, 100846a86e2SMadalin Bucur "%s: %d - %d\n", prevstr, 101846a86e2SMadalin Bucur first_fqid, last_fqid); 102846a86e2SMadalin Bucur } 103846a86e2SMadalin Bucur 104846a86e2SMadalin Bucur if (prev && abs(fq->fqid - prev->fqid) == 1 && 105846a86e2SMadalin Bucur str == prevstr) { 106846a86e2SMadalin Bucur last_fqid = fq->fqid; 107846a86e2SMadalin Bucur } else { 108846a86e2SMadalin Bucur first_fqid = fq->fqid; 109846a86e2SMadalin Bucur last_fqid = fq->fqid; 110846a86e2SMadalin Bucur } 111846a86e2SMadalin Bucur 112846a86e2SMadalin Bucur prev = fq; 113846a86e2SMadalin Bucur prevstr = str; 114846a86e2SMadalin Bucur i++; 115846a86e2SMadalin Bucur } 116846a86e2SMadalin Bucur 117846a86e2SMadalin Bucur if (prev) { 118846a86e2SMadalin Bucur if (last_fqid == first_fqid) 119846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, "%s: %d\n", prevstr, 120846a86e2SMadalin Bucur prev->fqid); 121846a86e2SMadalin Bucur else 122846a86e2SMadalin Bucur bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr, 123846a86e2SMadalin Bucur first_fqid, last_fqid); 124846a86e2SMadalin Bucur } 125846a86e2SMadalin Bucur 126846a86e2SMadalin Bucur return bytes; 127846a86e2SMadalin Bucur } 128846a86e2SMadalin Bucur 129846a86e2SMadalin Bucur static ssize_t dpaa_eth_show_bpids(struct device *dev, 130846a86e2SMadalin Bucur struct device_attribute *attr, char *buf) 131846a86e2SMadalin Bucur { 132846a86e2SMadalin Bucur struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 133846a86e2SMadalin Bucur ssize_t bytes = 0; 134846a86e2SMadalin Bucur int i = 0; 135846a86e2SMadalin Bucur 136846a86e2SMadalin Bucur for (i = 0; i < DPAA_BPS_NUM; i++) 137846a86e2SMadalin Bucur bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", 138846a86e2SMadalin Bucur priv->dpaa_bps[i]->bpid); 139846a86e2SMadalin Bucur 140846a86e2SMadalin Bucur return bytes; 141846a86e2SMadalin Bucur } 142846a86e2SMadalin Bucur 143846a86e2SMadalin Bucur static struct device_attribute dpaa_eth_attrs[] = { 144846a86e2SMadalin Bucur __ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL), 145846a86e2SMadalin Bucur __ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL), 146846a86e2SMadalin Bucur __ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL), 147846a86e2SMadalin Bucur }; 148846a86e2SMadalin Bucur 149846a86e2SMadalin Bucur void dpaa_eth_sysfs_init(struct device *dev) 150846a86e2SMadalin Bucur { 151846a86e2SMadalin Bucur int i; 152846a86e2SMadalin Bucur 153846a86e2SMadalin Bucur for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 154846a86e2SMadalin Bucur if (device_create_file(dev, &dpaa_eth_attrs[i])) { 155846a86e2SMadalin Bucur dev_err(dev, "Error creating sysfs file\n"); 156846a86e2SMadalin Bucur while (i > 0) 157846a86e2SMadalin Bucur device_remove_file(dev, &dpaa_eth_attrs[--i]); 158846a86e2SMadalin Bucur return; 159846a86e2SMadalin Bucur } 160846a86e2SMadalin Bucur } 161846a86e2SMadalin Bucur 162846a86e2SMadalin Bucur void dpaa_eth_sysfs_remove(struct device *dev) 163846a86e2SMadalin Bucur { 164846a86e2SMadalin Bucur int i; 165846a86e2SMadalin Bucur 166846a86e2SMadalin Bucur for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 167846a86e2SMadalin Bucur device_remove_file(dev, &dpaa_eth_attrs[i]); 168846a86e2SMadalin Bucur } 169