1 /*
2  *   Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
3  *   Copyright (c) 2014, I2SE GmbH
4  *
5  *   Permission to use, copy, modify, and/or distribute this software
6  *   for any purpose with or without fee is hereby granted, provided
7  *   that the above copyright notice and this permission notice appear
8  *   in all copies.
9  *
10  *   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  *   WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  *   WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
13  *   THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
14  *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  *   LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16  *   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17  *   CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*   This file contains debugging routines for use in the QCA7K driver.
21  */
22 
23 #include <linux/debugfs.h>
24 #include <linux/ethtool.h>
25 #include <linux/seq_file.h>
26 #include <linux/types.h>
27 
28 #include "qca_7k.h"
29 #include "qca_debug.h"
30 
31 #define QCASPI_MAX_REGS 0x20
32 
33 static const u16 qcaspi_spi_regs[] = {
34 	SPI_REG_BFR_SIZE,
35 	SPI_REG_WRBUF_SPC_AVA,
36 	SPI_REG_RDBUF_BYTE_AVA,
37 	SPI_REG_SPI_CONFIG,
38 	SPI_REG_SPI_STATUS,
39 	SPI_REG_INTR_CAUSE,
40 	SPI_REG_INTR_ENABLE,
41 	SPI_REG_RDBUF_WATERMARK,
42 	SPI_REG_WRBUF_WATERMARK,
43 	SPI_REG_SIGNATURE,
44 	SPI_REG_ACTION_CTRL
45 };
46 
47 /* The order of these strings must match the order of the fields in
48  * struct qcaspi_stats
49  * See qca_spi.h
50  */
51 static const char qcaspi_gstrings_stats[][ETH_GSTRING_LEN] = {
52 	"Triggered resets",
53 	"Device resets",
54 	"Reset timeouts",
55 	"Read errors",
56 	"Write errors",
57 	"Read buffer errors",
58 	"Write buffer errors",
59 	"Out of memory",
60 	"Write buffer misses",
61 	"Transmit ring full",
62 	"SPI errors",
63 	"Write verify errors",
64 	"Buffer available errors",
65 };
66 
67 #ifdef CONFIG_DEBUG_FS
68 
69 static int
70 qcaspi_info_show(struct seq_file *s, void *what)
71 {
72 	struct qcaspi *qca = s->private;
73 
74 	seq_printf(s, "RX buffer size   : %lu\n",
75 		   (unsigned long)qca->buffer_size);
76 
77 	seq_puts(s, "TX ring state    : ");
78 
79 	if (qca->txr.skb[qca->txr.head] == NULL)
80 		seq_puts(s, "empty");
81 	else if (qca->txr.skb[qca->txr.tail])
82 		seq_puts(s, "full");
83 	else
84 		seq_puts(s, "in use");
85 
86 	seq_puts(s, "\n");
87 
88 	seq_printf(s, "TX ring size     : %u\n",
89 		   qca->txr.size);
90 
91 	seq_printf(s, "Sync state       : %u (",
92 		   (unsigned int)qca->sync);
93 	switch (qca->sync) {
94 	case QCASPI_SYNC_UNKNOWN:
95 		seq_puts(s, "QCASPI_SYNC_UNKNOWN");
96 		break;
97 	case QCASPI_SYNC_RESET:
98 		seq_puts(s, "QCASPI_SYNC_RESET");
99 		break;
100 	case QCASPI_SYNC_READY:
101 		seq_puts(s, "QCASPI_SYNC_READY");
102 		break;
103 	default:
104 		seq_puts(s, "INVALID");
105 		break;
106 	}
107 	seq_puts(s, ")\n");
108 
109 	seq_printf(s, "IRQ              : %d\n",
110 		   qca->spi_dev->irq);
111 	seq_printf(s, "INTR REQ         : %u\n",
112 		   qca->intr_req);
113 	seq_printf(s, "INTR SVC         : %u\n",
114 		   qca->intr_svc);
115 
116 	seq_printf(s, "SPI max speed    : %lu\n",
117 		   (unsigned long)qca->spi_dev->max_speed_hz);
118 	seq_printf(s, "SPI mode         : %x\n",
119 		   qca->spi_dev->mode);
120 	seq_printf(s, "SPI chip select  : %u\n",
121 		   (unsigned int)qca->spi_dev->chip_select);
122 	seq_printf(s, "SPI legacy mode  : %u\n",
123 		   (unsigned int)qca->legacy_mode);
124 	seq_printf(s, "SPI burst length : %u\n",
125 		   (unsigned int)qca->burst_len);
126 
127 	return 0;
128 }
129 DEFINE_SHOW_ATTRIBUTE(qcaspi_info);
130 
131 void
132 qcaspi_init_device_debugfs(struct qcaspi *qca)
133 {
134 	struct dentry *device_root;
135 
136 	device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev), NULL);
137 	qca->device_root = device_root;
138 
139 	if (IS_ERR(device_root) || !device_root) {
140 		pr_warn("failed to create debugfs directory for %s\n",
141 			dev_name(&qca->net_dev->dev));
142 		return;
143 	}
144 	debugfs_create_file("info", S_IFREG | 0444, device_root, qca,
145 			    &qcaspi_info_fops);
146 }
147 
148 void
149 qcaspi_remove_device_debugfs(struct qcaspi *qca)
150 {
151 	debugfs_remove_recursive(qca->device_root);
152 }
153 
154 #else /* CONFIG_DEBUG_FS */
155 
156 void
157 qcaspi_init_device_debugfs(struct qcaspi *qca)
158 {
159 }
160 
161 void
162 qcaspi_remove_device_debugfs(struct qcaspi *qca)
163 {
164 }
165 
166 #endif
167 
168 static void
169 qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
170 {
171 	struct qcaspi *qca = netdev_priv(dev);
172 
173 	strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
174 	strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
175 	strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
176 	strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
177 		sizeof(p->bus_info));
178 }
179 
180 static int
181 qcaspi_get_link_ksettings(struct net_device *dev,
182 			  struct ethtool_link_ksettings *cmd)
183 {
184 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
185 	ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
186 
187 	cmd->base.speed = SPEED_10;
188 	cmd->base.duplex = DUPLEX_HALF;
189 	cmd->base.port = PORT_OTHER;
190 	cmd->base.autoneg = AUTONEG_DISABLE;
191 
192 	return 0;
193 }
194 
195 static void
196 qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
197 {
198 	struct qcaspi *qca = netdev_priv(dev);
199 	struct qcaspi_stats *st = &qca->stats;
200 
201 	memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
202 }
203 
204 static void
205 qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
206 {
207 	switch (stringset) {
208 	case ETH_SS_STATS:
209 		memcpy(buf, &qcaspi_gstrings_stats,
210 		       sizeof(qcaspi_gstrings_stats));
211 		break;
212 	default:
213 		WARN_ON(1);
214 		break;
215 	}
216 }
217 
218 static int
219 qcaspi_get_sset_count(struct net_device *dev, int sset)
220 {
221 	switch (sset) {
222 	case ETH_SS_STATS:
223 		return ARRAY_SIZE(qcaspi_gstrings_stats);
224 	default:
225 		return -EINVAL;
226 	}
227 }
228 
229 static int
230 qcaspi_get_regs_len(struct net_device *dev)
231 {
232 	return sizeof(u32) * QCASPI_MAX_REGS;
233 }
234 
235 static void
236 qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
237 {
238 	struct qcaspi *qca = netdev_priv(dev);
239 	u32 *regs_buff = p;
240 	unsigned int i;
241 
242 	regs->version = 1;
243 	memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
244 
245 	for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
246 		u16 offset, value;
247 
248 		qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
249 		offset = qcaspi_spi_regs[i] >> 8;
250 		regs_buff[offset] = value;
251 	}
252 }
253 
254 static void
255 qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
256 {
257 	struct qcaspi *qca = netdev_priv(dev);
258 
259 	ring->rx_max_pending = 4;
260 	ring->tx_max_pending = TX_RING_MAX_LEN;
261 	ring->rx_pending = 4;
262 	ring->tx_pending = qca->txr.count;
263 }
264 
265 static int
266 qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
267 {
268 	const struct net_device_ops *ops = dev->netdev_ops;
269 	struct qcaspi *qca = netdev_priv(dev);
270 
271 	if ((ring->rx_pending) ||
272 	    (ring->rx_mini_pending) ||
273 	    (ring->rx_jumbo_pending))
274 		return -EINVAL;
275 
276 	if (netif_running(dev))
277 		ops->ndo_stop(dev);
278 
279 	qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
280 	qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
281 
282 	if (netif_running(dev))
283 		ops->ndo_open(dev);
284 
285 	return 0;
286 }
287 
288 static const struct ethtool_ops qcaspi_ethtool_ops = {
289 	.get_drvinfo = qcaspi_get_drvinfo,
290 	.get_link = ethtool_op_get_link,
291 	.get_ethtool_stats = qcaspi_get_ethtool_stats,
292 	.get_strings = qcaspi_get_strings,
293 	.get_sset_count = qcaspi_get_sset_count,
294 	.get_regs_len = qcaspi_get_regs_len,
295 	.get_regs = qcaspi_get_regs,
296 	.get_ringparam = qcaspi_get_ringparam,
297 	.set_ringparam = qcaspi_set_ringparam,
298 	.get_link_ksettings = qcaspi_get_link_ksettings,
299 };
300 
301 void qcaspi_set_ethtool_ops(struct net_device *dev)
302 {
303 	dev->ethtool_ops = &qcaspi_ethtool_ops;
304 }
305