xref: /linux/drivers/net/ethernet/qualcomm/qca_debug.c (revision 47330f9bdf240f5a582f756cf93354281b36453a)
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 
130 static int
131 qcaspi_info_open(struct inode *inode, struct file *file)
132 {
133 	return single_open(file, qcaspi_info_show, inode->i_private);
134 }
135 
136 static const struct file_operations qcaspi_info_ops = {
137 	.open = qcaspi_info_open,
138 	.read = seq_read,
139 	.llseek = seq_lseek,
140 	.release = single_release,
141 };
142 
143 void
144 qcaspi_init_device_debugfs(struct qcaspi *qca)
145 {
146 	struct dentry *device_root;
147 
148 	device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev), NULL);
149 	qca->device_root = device_root;
150 
151 	if (IS_ERR(device_root) || !device_root) {
152 		pr_warn("failed to create debugfs directory for %s\n",
153 			dev_name(&qca->net_dev->dev));
154 		return;
155 	}
156 	debugfs_create_file("info", S_IFREG | 0444, device_root, qca,
157 			    &qcaspi_info_ops);
158 }
159 
160 void
161 qcaspi_remove_device_debugfs(struct qcaspi *qca)
162 {
163 	debugfs_remove_recursive(qca->device_root);
164 }
165 
166 #else /* CONFIG_DEBUG_FS */
167 
168 void
169 qcaspi_init_device_debugfs(struct qcaspi *qca)
170 {
171 }
172 
173 void
174 qcaspi_remove_device_debugfs(struct qcaspi *qca)
175 {
176 }
177 
178 #endif
179 
180 static void
181 qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
182 {
183 	struct qcaspi *qca = netdev_priv(dev);
184 
185 	strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
186 	strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
187 	strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
188 	strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
189 		sizeof(p->bus_info));
190 }
191 
192 static int
193 qcaspi_get_link_ksettings(struct net_device *dev,
194 			  struct ethtool_link_ksettings *cmd)
195 {
196 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
197 	ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
198 
199 	cmd->base.speed = SPEED_10;
200 	cmd->base.duplex = DUPLEX_HALF;
201 	cmd->base.port = PORT_OTHER;
202 	cmd->base.autoneg = AUTONEG_DISABLE;
203 
204 	return 0;
205 }
206 
207 static void
208 qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
209 {
210 	struct qcaspi *qca = netdev_priv(dev);
211 	struct qcaspi_stats *st = &qca->stats;
212 
213 	memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
214 }
215 
216 static void
217 qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
218 {
219 	switch (stringset) {
220 	case ETH_SS_STATS:
221 		memcpy(buf, &qcaspi_gstrings_stats,
222 		       sizeof(qcaspi_gstrings_stats));
223 		break;
224 	default:
225 		WARN_ON(1);
226 		break;
227 	}
228 }
229 
230 static int
231 qcaspi_get_sset_count(struct net_device *dev, int sset)
232 {
233 	switch (sset) {
234 	case ETH_SS_STATS:
235 		return ARRAY_SIZE(qcaspi_gstrings_stats);
236 	default:
237 		return -EINVAL;
238 	}
239 }
240 
241 static int
242 qcaspi_get_regs_len(struct net_device *dev)
243 {
244 	return sizeof(u32) * QCASPI_MAX_REGS;
245 }
246 
247 static void
248 qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
249 {
250 	struct qcaspi *qca = netdev_priv(dev);
251 	u32 *regs_buff = p;
252 	unsigned int i;
253 
254 	regs->version = 1;
255 	memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
256 
257 	for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
258 		u16 offset, value;
259 
260 		qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
261 		offset = qcaspi_spi_regs[i] >> 8;
262 		regs_buff[offset] = value;
263 	}
264 }
265 
266 static void
267 qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
268 {
269 	struct qcaspi *qca = netdev_priv(dev);
270 
271 	ring->rx_max_pending = 4;
272 	ring->tx_max_pending = TX_RING_MAX_LEN;
273 	ring->rx_pending = 4;
274 	ring->tx_pending = qca->txr.count;
275 }
276 
277 static int
278 qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
279 {
280 	const struct net_device_ops *ops = dev->netdev_ops;
281 	struct qcaspi *qca = netdev_priv(dev);
282 
283 	if ((ring->rx_pending) ||
284 	    (ring->rx_mini_pending) ||
285 	    (ring->rx_jumbo_pending))
286 		return -EINVAL;
287 
288 	if (netif_running(dev))
289 		ops->ndo_stop(dev);
290 
291 	qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
292 	qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
293 
294 	if (netif_running(dev))
295 		ops->ndo_open(dev);
296 
297 	return 0;
298 }
299 
300 static const struct ethtool_ops qcaspi_ethtool_ops = {
301 	.get_drvinfo = qcaspi_get_drvinfo,
302 	.get_link = ethtool_op_get_link,
303 	.get_ethtool_stats = qcaspi_get_ethtool_stats,
304 	.get_strings = qcaspi_get_strings,
305 	.get_sset_count = qcaspi_get_sset_count,
306 	.get_regs_len = qcaspi_get_regs_len,
307 	.get_regs = qcaspi_get_regs,
308 	.get_ringparam = qcaspi_get_ringparam,
309 	.set_ringparam = qcaspi_set_ringparam,
310 	.get_link_ksettings = qcaspi_get_link_ksettings,
311 };
312 
313 void qcaspi_set_ethtool_ops(struct net_device *dev)
314 {
315 	dev->ethtool_ops = &qcaspi_ethtool_ops;
316 }
317