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