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