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