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