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 
135846a86e2SMadalin Bucur 	bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n",
136f07f3004SMadalin Bucur 				  priv->dpaa_bp->bpid);
137846a86e2SMadalin Bucur 
138846a86e2SMadalin Bucur 	return bytes;
139846a86e2SMadalin Bucur }
140846a86e2SMadalin Bucur 
141846a86e2SMadalin Bucur static struct device_attribute dpaa_eth_attrs[] = {
142846a86e2SMadalin Bucur 	__ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL),
143846a86e2SMadalin Bucur 	__ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL),
144846a86e2SMadalin Bucur 	__ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL),
145846a86e2SMadalin Bucur };
146846a86e2SMadalin Bucur 
147846a86e2SMadalin Bucur void dpaa_eth_sysfs_init(struct device *dev)
148846a86e2SMadalin Bucur {
149846a86e2SMadalin Bucur 	int i;
150846a86e2SMadalin Bucur 
151846a86e2SMadalin Bucur 	for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
152846a86e2SMadalin Bucur 		if (device_create_file(dev, &dpaa_eth_attrs[i])) {
153846a86e2SMadalin Bucur 			dev_err(dev, "Error creating sysfs file\n");
154846a86e2SMadalin Bucur 			while (i > 0)
155846a86e2SMadalin Bucur 				device_remove_file(dev, &dpaa_eth_attrs[--i]);
156846a86e2SMadalin Bucur 			return;
157846a86e2SMadalin Bucur 		}
158846a86e2SMadalin Bucur }
159846a86e2SMadalin Bucur 
160846a86e2SMadalin Bucur void dpaa_eth_sysfs_remove(struct device *dev)
161846a86e2SMadalin Bucur {
162846a86e2SMadalin Bucur 	int i;
163846a86e2SMadalin Bucur 
164846a86e2SMadalin Bucur 	for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
165846a86e2SMadalin Bucur 		device_remove_file(dev, &dpaa_eth_attrs[i]);
166846a86e2SMadalin Bucur }
167