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
22static 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 */
40static 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
59static int
60qcaspi_info_show(struct seq_file *s, void *what)
61{
62 struct qcaspi *qca = s->private;
63
64 seq_printf(m: s, fmt: "RX buffer size : %lu\n",
65 (unsigned long)qca->buffer_size);
66
67 seq_puts(m: s, s: "TX ring state : ");
68
69 if (qca->txr.skb[qca->txr.head] == NULL)
70 seq_puts(m: s, s: "empty");
71 else if (qca->txr.skb[qca->txr.tail])
72 seq_puts(m: s, s: "full");
73 else
74 seq_puts(m: s, s: "in use");
75
76 seq_puts(m: s, s: "\n");
77
78 seq_printf(m: s, fmt: "TX ring size : %u\n",
79 qca->txr.size);
80
81 seq_printf(m: s, fmt: "Sync state : %u (",
82 (unsigned int)qca->sync);
83 switch (qca->sync) {
84 case QCASPI_SYNC_UNKNOWN:
85 seq_puts(m: s, s: "QCASPI_SYNC_UNKNOWN");
86 break;
87 case QCASPI_SYNC_RESET:
88 seq_puts(m: s, s: "QCASPI_SYNC_RESET");
89 break;
90 case QCASPI_SYNC_READY:
91 seq_puts(m: s, s: "QCASPI_SYNC_READY");
92 break;
93 default:
94 seq_puts(m: s, s: "INVALID");
95 break;
96 }
97 seq_puts(m: s, s: ")\n");
98
99 seq_printf(m: s, fmt: "IRQ : %d\n",
100 qca->spi_dev->irq);
101 seq_printf(m: s, fmt: "INTR REQ : %u\n",
102 qca->intr_req);
103 seq_printf(m: s, fmt: "INTR SVC : %u\n",
104 qca->intr_svc);
105
106 seq_printf(m: s, fmt: "SPI max speed : %lu\n",
107 (unsigned long)qca->spi_dev->max_speed_hz);
108 seq_printf(m: s, fmt: "SPI mode : %x\n",
109 qca->spi_dev->mode);
110 seq_printf(m: s, fmt: "SPI chip select : %u\n",
111 (unsigned int)spi_get_chipselect(spi: qca->spi_dev, idx: 0));
112 seq_printf(m: s, fmt: "SPI legacy mode : %u\n",
113 (unsigned int)qca->legacy_mode);
114 seq_printf(m: s, fmt: "SPI burst length : %u\n",
115 (unsigned int)qca->burst_len);
116
117 return 0;
118}
119DEFINE_SHOW_ATTRIBUTE(qcaspi_info);
120
121void
122qcaspi_init_device_debugfs(struct qcaspi *qca)
123{
124 qca->device_root = debugfs_create_dir(name: dev_name(dev: &qca->net_dev->dev),
125 NULL);
126
127 debugfs_create_file(name: "info", S_IFREG | 0444, parent: qca->device_root, data: qca,
128 fops: &qcaspi_info_fops);
129}
130
131void
132qcaspi_remove_device_debugfs(struct qcaspi *qca)
133{
134 debugfs_remove_recursive(dentry: qca->device_root);
135}
136
137#else /* CONFIG_DEBUG_FS */
138
139void
140qcaspi_init_device_debugfs(struct qcaspi *qca)
141{
142}
143
144void
145qcaspi_remove_device_debugfs(struct qcaspi *qca)
146{
147}
148
149#endif
150
151static void
152qcaspi_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
163static int
164qcaspi_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
178static void
179qcaspi_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
187static void
188qcaspi_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
201static int
202qcaspi_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
212static int
213qcaspi_get_regs_len(struct net_device *dev)
214{
215 return sizeof(u32) * QCASPI_MAX_REGS;
216}
217
218static void
219qcaspi_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, reg: qcaspi_spi_regs[i], result: &value);
232 offset = qcaspi_spi_regs[i] >> 8;
233 regs_buff[offset] = value;
234 }
235}
236
237static void
238qcaspi_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
250static int
251qcaspi_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(k: 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(k: qca->spi_thread);
270
271 return 0;
272}
273
274static 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
287void qcaspi_set_ethtool_ops(struct net_device *dev)
288{
289 dev->ethtool_ops = &qcaspi_ethtool_ops;
290}
291

source code of linux/drivers/net/ethernet/qualcomm/qca_debug.c