xref: /linux/drivers/net/ethernet/qualcomm/qca_debug.c (revision d5a7fc58da039903b332041e8c67daae36f08b50)
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
qcaspi_info_show(struct seq_file * s,void * what)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             : %lx\n",
102 		   qca->intr);
103 
104 	seq_printf(s, "SPI max speed    : %lu\n",
105 		   (unsigned long)qca->spi_dev->max_speed_hz);
106 	seq_printf(s, "SPI mode         : %x\n",
107 		   qca->spi_dev->mode);
108 	seq_printf(s, "SPI chip select  : %u\n",
109 		   (unsigned int)spi_get_chipselect(qca->spi_dev, 0));
110 	seq_printf(s, "SPI legacy mode  : %u\n",
111 		   (unsigned int)qca->legacy_mode);
112 	seq_printf(s, "SPI burst length : %u\n",
113 		   (unsigned int)qca->burst_len);
114 
115 	return 0;
116 }
117 DEFINE_SHOW_ATTRIBUTE(qcaspi_info);
118 
119 void
qcaspi_init_device_debugfs(struct qcaspi * qca)120 qcaspi_init_device_debugfs(struct qcaspi *qca)
121 {
122 	qca->device_root = debugfs_create_dir(dev_name(&qca->net_dev->dev),
123 					      NULL);
124 
125 	debugfs_create_file("info", S_IFREG | 0444, qca->device_root, qca,
126 			    &qcaspi_info_fops);
127 }
128 
129 void
qcaspi_remove_device_debugfs(struct qcaspi * qca)130 qcaspi_remove_device_debugfs(struct qcaspi *qca)
131 {
132 	debugfs_remove_recursive(qca->device_root);
133 }
134 
135 #else /* CONFIG_DEBUG_FS */
136 
137 void
qcaspi_init_device_debugfs(struct qcaspi * qca)138 qcaspi_init_device_debugfs(struct qcaspi *qca)
139 {
140 }
141 
142 void
qcaspi_remove_device_debugfs(struct qcaspi * qca)143 qcaspi_remove_device_debugfs(struct qcaspi *qca)
144 {
145 }
146 
147 #endif
148 
149 static void
qcaspi_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * p)150 qcaspi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *p)
151 {
152 	struct qcaspi *qca = netdev_priv(dev);
153 
154 	strscpy(p->driver, QCASPI_DRV_NAME, sizeof(p->driver));
155 	strscpy(p->version, QCASPI_DRV_VERSION, sizeof(p->version));
156 	strscpy(p->fw_version, "QCA7000", sizeof(p->fw_version));
157 	strscpy(p->bus_info, dev_name(&qca->spi_dev->dev),
158 		sizeof(p->bus_info));
159 }
160 
161 static int
qcaspi_get_link_ksettings(struct net_device * dev,struct ethtool_link_ksettings * cmd)162 qcaspi_get_link_ksettings(struct net_device *dev,
163 			  struct ethtool_link_ksettings *cmd)
164 {
165 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
166 	ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half);
167 
168 	cmd->base.speed = SPEED_10;
169 	cmd->base.duplex = DUPLEX_HALF;
170 	cmd->base.port = PORT_OTHER;
171 	cmd->base.autoneg = AUTONEG_DISABLE;
172 
173 	return 0;
174 }
175 
176 static void
qcaspi_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * estats,u64 * data)177 qcaspi_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *data)
178 {
179 	struct qcaspi *qca = netdev_priv(dev);
180 	struct qcaspi_stats *st = &qca->stats;
181 
182 	memcpy(data, st, ARRAY_SIZE(qcaspi_gstrings_stats) * sizeof(u64));
183 }
184 
185 static void
qcaspi_get_strings(struct net_device * dev,u32 stringset,u8 * buf)186 qcaspi_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
187 {
188 	switch (stringset) {
189 	case ETH_SS_STATS:
190 		memcpy(buf, &qcaspi_gstrings_stats,
191 		       sizeof(qcaspi_gstrings_stats));
192 		break;
193 	default:
194 		WARN_ON(1);
195 		break;
196 	}
197 }
198 
199 static int
qcaspi_get_sset_count(struct net_device * dev,int sset)200 qcaspi_get_sset_count(struct net_device *dev, int sset)
201 {
202 	switch (sset) {
203 	case ETH_SS_STATS:
204 		return ARRAY_SIZE(qcaspi_gstrings_stats);
205 	default:
206 		return -EINVAL;
207 	}
208 }
209 
210 static int
qcaspi_get_regs_len(struct net_device * dev)211 qcaspi_get_regs_len(struct net_device *dev)
212 {
213 	return sizeof(u32) * QCASPI_MAX_REGS;
214 }
215 
216 static void
qcaspi_get_regs(struct net_device * dev,struct ethtool_regs * regs,void * p)217 qcaspi_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
218 {
219 	struct qcaspi *qca = netdev_priv(dev);
220 	u32 *regs_buff = p;
221 	unsigned int i;
222 
223 	regs->version = 1;
224 	memset(regs_buff, 0, sizeof(u32) * QCASPI_MAX_REGS);
225 
226 	for (i = 0; i < ARRAY_SIZE(qcaspi_spi_regs); i++) {
227 		u16 offset, value;
228 
229 		qcaspi_read_register(qca, qcaspi_spi_regs[i], &value);
230 		offset = qcaspi_spi_regs[i] >> 8;
231 		regs_buff[offset] = value;
232 	}
233 }
234 
235 static void
qcaspi_get_ringparam(struct net_device * dev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)236 qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring,
237 		     struct kernel_ethtool_ringparam *kernel_ring,
238 		     struct netlink_ext_ack *extack)
239 {
240 	struct qcaspi *qca = netdev_priv(dev);
241 
242 	ring->rx_max_pending = QCASPI_RX_MAX_FRAMES;
243 	ring->tx_max_pending = QCASPI_TX_RING_MAX_LEN;
244 	ring->rx_pending = QCASPI_RX_MAX_FRAMES;
245 	ring->tx_pending = qca->txr.count;
246 }
247 
248 static int
qcaspi_set_ringparam(struct net_device * dev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)249 qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring,
250 		     struct kernel_ethtool_ringparam *kernel_ring,
251 		     struct netlink_ext_ack *extack)
252 {
253 	struct qcaspi *qca = netdev_priv(dev);
254 
255 	if (ring->rx_pending != QCASPI_RX_MAX_FRAMES ||
256 	    (ring->rx_mini_pending) ||
257 	    (ring->rx_jumbo_pending))
258 		return -EINVAL;
259 
260 	if (qca->spi_thread)
261 		kthread_park(qca->spi_thread);
262 
263 	qca->txr.count = max_t(u32, ring->tx_pending, QCASPI_TX_RING_MIN_LEN);
264 	qca->txr.count = min_t(u16, qca->txr.count, QCASPI_TX_RING_MAX_LEN);
265 
266 	if (qca->spi_thread)
267 		kthread_unpark(qca->spi_thread);
268 
269 	return 0;
270 }
271 
272 static const struct ethtool_ops qcaspi_ethtool_ops = {
273 	.get_drvinfo = qcaspi_get_drvinfo,
274 	.get_link = ethtool_op_get_link,
275 	.get_ethtool_stats = qcaspi_get_ethtool_stats,
276 	.get_strings = qcaspi_get_strings,
277 	.get_sset_count = qcaspi_get_sset_count,
278 	.get_regs_len = qcaspi_get_regs_len,
279 	.get_regs = qcaspi_get_regs,
280 	.get_ringparam = qcaspi_get_ringparam,
281 	.set_ringparam = qcaspi_set_ringparam,
282 	.get_link_ksettings = qcaspi_get_link_ksettings,
283 };
284 
qcaspi_set_ethtool_ops(struct net_device * dev)285 void qcaspi_set_ethtool_ops(struct net_device *dev)
286 {
287 	dev->ethtool_ops = &qcaspi_ethtool_ops;
288 }
289