xref: /linux/drivers/net/ethernet/qualcomm/qca_debug.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
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 };
64 
65 #ifdef CONFIG_DEBUG_FS
66 
67 static int
68 qcaspi_info_show(struct seq_file *s, void *what)
69 {
70 	struct qcaspi *qca = s->private;
71 
72 	seq_printf(s, "RX buffer size   : %lu\n",
73 		   (unsigned long)qca->buffer_size);
74 
75 	seq_puts(s, "TX ring state    : ");
76 
77 	if (qca->txr.skb[qca->txr.head] == NULL)
78 		seq_puts(s, "empty");
79 	else if (qca->txr.skb[qca->txr.tail])
80 		seq_puts(s, "full");
81 	else
82 		seq_puts(s, "in use");
83 
84 	seq_puts(s, "\n");
85 
86 	seq_printf(s, "TX ring size     : %u\n",
87 		   qca->txr.size);
88 
89 	seq_printf(s, "Sync state       : %u (",
90 		   (unsigned int)qca->sync);
91 	switch (qca->sync) {
92 	case QCASPI_SYNC_UNKNOWN:
93 		seq_puts(s, "QCASPI_SYNC_UNKNOWN");
94 		break;
95 	case QCASPI_SYNC_RESET:
96 		seq_puts(s, "QCASPI_SYNC_RESET");
97 		break;
98 	case QCASPI_SYNC_READY:
99 		seq_puts(s, "QCASPI_SYNC_READY");
100 		break;
101 	default:
102 		seq_puts(s, "INVALID");
103 		break;
104 	}
105 	seq_puts(s, ")\n");
106 
107 	seq_printf(s, "IRQ              : %d\n",
108 		   qca->spi_dev->irq);
109 	seq_printf(s, "INTR REQ         : %u\n",
110 		   qca->intr_req);
111 	seq_printf(s, "INTR SVC         : %u\n",
112 		   qca->intr_svc);
113 
114 	seq_printf(s, "SPI max speed    : %lu\n",
115 		   (unsigned long)qca->spi_dev->max_speed_hz);
116 	seq_printf(s, "SPI mode         : %x\n",
117 		   qca->spi_dev->mode);
118 	seq_printf(s, "SPI chip select  : %u\n",
119 		   (unsigned int)qca->spi_dev->chip_select);
120 	seq_printf(s, "SPI legacy mode  : %u\n",
121 		   (unsigned int)qca->legacy_mode);
122 	seq_printf(s, "SPI burst length : %u\n",
123 		   (unsigned int)qca->burst_len);
124 
125 	return 0;
126 }
127 
128 static int
129 qcaspi_info_open(struct inode *inode, struct file *file)
130 {
131 	return single_open(file, qcaspi_info_show, inode->i_private);
132 }
133 
134 static const struct file_operations qcaspi_info_ops = {
135 	.open = qcaspi_info_open,
136 	.read = seq_read,
137 	.llseek = seq_lseek,
138 	.release = single_release,
139 };
140 
141 void
142 qcaspi_init_device_debugfs(struct qcaspi *qca)
143 {
144 	struct dentry *device_root;
145 
146 	device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev), NULL);
147 	qca->device_root = device_root;
148 
149 	if (IS_ERR(device_root) || !device_root) {
150 		pr_warn("failed to create debugfs directory for %s\n",
151 			dev_name(&qca->net_dev->dev));
152 		return;
153 	}
154 	debugfs_create_file("info", S_IFREG | S_IRUGO, device_root, qca,
155 			    &qcaspi_info_ops);
156 }
157 
158 void
159 qcaspi_remove_device_debugfs(struct qcaspi *qca)
160 {
161 	debugfs_remove_recursive(qca->device_root);
162 }
163 
164 #else /* CONFIG_DEBUG_FS */
165 
166 void
167 qcaspi_init_device_debugfs(struct qcaspi *qca)
168 {
169 }
170 
171 void
172 qcaspi_remove_device_debugfs(struct qcaspi *qca)
173 {
174 }
175 
176 #endif
177 
178 static void
179 qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
180 {
181 	struct qcaspi *qca = netdev_priv(dev);
182 
183 	strlcpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
184 	strlcpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
185 	strlcpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
186 	strlcpy(p->bus_info, dev_name(&qca->spi_dev->dev),
187 		sizeof(p->bus_info));
188 }
189 
190 static int
191 qcaspi_get_link_ksettings(struct net_device *dev,
192 			  struct ethtool_link_ksettings *cmd)
193 {
194 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
195 	ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
196 
197 	cmd->base.speed = SPEED_10;
198 	cmd->base.duplex = DUPLEX_HALF;
199 	cmd->base.port = PORT_OTHER;
200 	cmd->base.autoneg = AUTONEG_DISABLE;
201 
202 	return 0;
203 }
204 
205 static void
206 qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
207 {
208 	struct qcaspi *qca = netdev_priv(dev);
209 	struct qcaspi_stats *st = &qca->stats;
210 
211 	memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
212 }
213 
214 static void
215 qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
216 {
217 	switch (stringset) {
218 	case ETH_SS_STATS:
219 		memcpy(buf, &qcaspi_gstrings_stats,
220 		       sizeof(qcaspi_gstrings_stats));
221 		break;
222 	default:
223 		WARN_ON(1);
224 		break;
225 	}
226 }
227 
228 static int
229 qcaspi_get_sset_count(struct net_device *dev, int sset)
230 {
231 	switch (sset) {
232 	case ETH_SS_STATS:
233 		return ARRAY_SIZE(qcaspi_gstrings_stats);
234 	default:
235 		return -EINVAL;
236 	}
237 }
238 
239 static int
240 qcaspi_get_regs_len(struct net_device *dev)
241 {
242 	return sizeof(u32) * QCASPI_MAX_REGS;
243 }
244 
245 static void
246 qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
247 {
248 	struct qcaspi *qca = netdev_priv(dev);
249 	u32 *regs_buff = p;
250 	unsigned int i;
251 
252 	regs->version = 1;
253 	memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
254 
255 	for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
256 		u16 offset, value;
257 
258 		qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
259 		offset = qcaspi_spi_regs[i] >> 8;
260 		regs_buff[offset] = value;
261 	}
262 }
263 
264 static void
265 qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
266 {
267 	struct qcaspi *qca = netdev_priv(dev);
268 
269 	ring->rx_max_pending = 4;
270 	ring->tx_max_pending = TX_RING_MAX_LEN;
271 	ring->rx_pending = 4;
272 	ring->tx_pending = qca->txr.count;
273 }
274 
275 static int
276 qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
277 {
278 	struct qcaspi *qca = netdev_priv(dev);
279 
280 	if ((ring->rx_pending) ||
281 	    (ring->rx_mini_pending) ||
282 	    (ring->rx_jumbo_pending))
283 		return -EINVAL;
284 
285 	if (netif_running(dev))
286 		qcaspi_netdev_close(dev);
287 
288 	qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN);
289 	qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
290 
291 	if (netif_running(dev))
292 		qcaspi_netdev_open(dev);
293 
294 	return 0;
295 }
296 
297 static const struct ethtool_ops qcaspi_ethtool_ops = {
298 	.get_drvinfo = qcaspi_get_drvinfo,
299 	.get_link = ethtool_op_get_link,
300 	.get_ethtool_stats = qcaspi_get_ethtool_stats,
301 	.get_strings = qcaspi_get_strings,
302 	.get_sset_count = qcaspi_get_sset_count,
303 	.get_regs_len = qcaspi_get_regs_len,
304 	.get_regs = qcaspi_get_regs,
305 	.get_ringparam = qcaspi_get_ringparam,
306 	.set_ringparam = qcaspi_set_ringparam,
307 	.get_link_ksettings = qcaspi_get_link_ksettings,
308 };
309 
310 void qcaspi_set_ethtool_ops(struct net_device *dev)
311 {
312 	dev->ethtool_ops = &qcaspi_ethtool_ops;
313 }
314