]> Git Repo - J-linux.git/blob - drivers/net/ethernet/qualcomm/qca_debug.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / ethernet / qualcomm / qca_debug.c
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, "FLAGS            : %lx\n",
102                    qca->flags);
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
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
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
138 qcaspi_init_device_debugfs(struct qcaspi *qca)
139 {
140 }
141
142 void
143 qcaspi_remove_device_debugfs(struct qcaspi *qca)
144 {
145 }
146
147 #endif
148
149 static void
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
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
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
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
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
211 qcaspi_get_regs_len(struct net_device *dev)
212 {
213         return sizeof(u32) * QCASPI_MAX_REGS;
214 }
215
216 static void
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
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
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
285 void qcaspi_set_ethtool_ops(struct net_device *dev)
286 {
287         dev->ethtool_ops = &qcaspi_ethtool_ops;
288 }
This page took 0.04566 seconds and 4 git commands to generate.