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 module implements the Qualcomm Atheros SPI protocol for |
21 | * kernel-based SPI device; it is essentially an Ethernet-to-SPI |
22 | * serial converter; |
23 | */ |
24 | |
25 | #include <linux/errno.h> |
26 | #include <linux/etherdevice.h> |
27 | #include <linux/if_arp.h> |
28 | #include <linux/if_ether.h> |
29 | #include <linux/init.h> |
30 | #include <linux/interrupt.h> |
31 | #include <linux/jiffies.h> |
32 | #include <linux/kernel.h> |
33 | #include <linux/kthread.h> |
34 | #include <linux/module.h> |
35 | #include <linux/moduleparam.h> |
36 | #include <linux/netdevice.h> |
37 | #include <linux/of.h> |
38 | #include <linux/of_net.h> |
39 | #include <linux/sched.h> |
40 | #include <linux/skbuff.h> |
41 | #include <linux/spi/spi.h> |
42 | #include <linux/types.h> |
43 | |
44 | #include "qca_7k.h" |
45 | #include "qca_7k_common.h" |
46 | #include "qca_debug.h" |
47 | #include "qca_spi.h" |
48 | |
49 | #define MAX_DMA_BURST_LEN 5000 |
50 | |
51 | /* Modules parameters */ |
52 | #define QCASPI_CLK_SPEED_MIN 1000000 |
53 | #define QCASPI_CLK_SPEED_MAX 16000000 |
54 | #define QCASPI_CLK_SPEED 8000000 |
55 | static int qcaspi_clkspeed; |
56 | module_param(qcaspi_clkspeed, int, 0); |
57 | MODULE_PARM_DESC(qcaspi_clkspeed, "SPI bus clock speed (Hz). Use 1000000-16000000." ); |
58 | |
59 | #define QCASPI_BURST_LEN_MIN 1 |
60 | #define QCASPI_BURST_LEN_MAX MAX_DMA_BURST_LEN |
61 | static int qcaspi_burst_len = MAX_DMA_BURST_LEN; |
62 | module_param(qcaspi_burst_len, int, 0); |
63 | MODULE_PARM_DESC(qcaspi_burst_len, "Number of data bytes per burst. Use 1-5000." ); |
64 | |
65 | #define QCASPI_PLUGGABLE_MIN 0 |
66 | #define QCASPI_PLUGGABLE_MAX 1 |
67 | static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN; |
68 | module_param(qcaspi_pluggable, int, 0); |
69 | MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no)." ); |
70 | |
71 | #define QCASPI_WRITE_VERIFY_MIN 0 |
72 | #define QCASPI_WRITE_VERIFY_MAX 3 |
73 | static int wr_verify = QCASPI_WRITE_VERIFY_MIN; |
74 | module_param(wr_verify, int, 0); |
75 | MODULE_PARM_DESC(wr_verify, "SPI register write verify trails. Use 0-3." ); |
76 | |
77 | #define QCASPI_TX_TIMEOUT (1 * HZ) |
78 | #define QCASPI_QCA7K_REBOOT_TIME_MS 1000 |
79 | |
80 | static void |
81 | start_spi_intr_handling(struct qcaspi *qca, u16 *intr_cause) |
82 | { |
83 | *intr_cause = 0; |
84 | |
85 | qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, value: 0, retry: wr_verify); |
86 | qcaspi_read_register(qca, SPI_REG_INTR_CAUSE, result: intr_cause); |
87 | netdev_dbg(qca->net_dev, "interrupts: 0x%04x\n" , *intr_cause); |
88 | } |
89 | |
90 | static void |
91 | end_spi_intr_handling(struct qcaspi *qca, u16 intr_cause) |
92 | { |
93 | u16 intr_enable = (SPI_INT_CPU_ON | |
94 | SPI_INT_PKT_AVLBL | |
95 | SPI_INT_RDBUF_ERR | |
96 | SPI_INT_WRBUF_ERR); |
97 | |
98 | qcaspi_write_register(qca, SPI_REG_INTR_CAUSE, value: intr_cause, retry: 0); |
99 | qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, value: intr_enable, retry: wr_verify); |
100 | netdev_dbg(qca->net_dev, "acking int: 0x%04x\n" , intr_cause); |
101 | } |
102 | |
103 | static u32 |
104 | qcaspi_write_burst(struct qcaspi *qca, u8 *src, u32 len) |
105 | { |
106 | __be16 cmd; |
107 | struct spi_message msg; |
108 | struct spi_transfer transfer[2]; |
109 | int ret; |
110 | |
111 | memset(&transfer, 0, sizeof(transfer)); |
112 | spi_message_init(m: &msg); |
113 | |
114 | cmd = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL); |
115 | transfer[0].tx_buf = &cmd; |
116 | transfer[0].len = QCASPI_CMD_LEN; |
117 | transfer[1].tx_buf = src; |
118 | transfer[1].len = len; |
119 | |
120 | spi_message_add_tail(t: &transfer[0], m: &msg); |
121 | spi_message_add_tail(t: &transfer[1], m: &msg); |
122 | ret = spi_sync(spi: qca->spi_dev, message: &msg); |
123 | |
124 | if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) { |
125 | qcaspi_spi_error(qca); |
126 | return 0; |
127 | } |
128 | |
129 | return len; |
130 | } |
131 | |
132 | static u32 |
133 | qcaspi_write_legacy(struct qcaspi *qca, u8 *src, u32 len) |
134 | { |
135 | struct spi_message msg; |
136 | struct spi_transfer transfer; |
137 | int ret; |
138 | |
139 | memset(&transfer, 0, sizeof(transfer)); |
140 | spi_message_init(m: &msg); |
141 | |
142 | transfer.tx_buf = src; |
143 | transfer.len = len; |
144 | |
145 | spi_message_add_tail(t: &transfer, m: &msg); |
146 | ret = spi_sync(spi: qca->spi_dev, message: &msg); |
147 | |
148 | if (ret || (msg.actual_length != len)) { |
149 | qcaspi_spi_error(qca); |
150 | return 0; |
151 | } |
152 | |
153 | return len; |
154 | } |
155 | |
156 | static u32 |
157 | qcaspi_read_burst(struct qcaspi *qca, u8 *dst, u32 len) |
158 | { |
159 | struct spi_message msg; |
160 | __be16 cmd; |
161 | struct spi_transfer transfer[2]; |
162 | int ret; |
163 | |
164 | memset(&transfer, 0, sizeof(transfer)); |
165 | spi_message_init(m: &msg); |
166 | |
167 | cmd = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL); |
168 | transfer[0].tx_buf = &cmd; |
169 | transfer[0].len = QCASPI_CMD_LEN; |
170 | transfer[1].rx_buf = dst; |
171 | transfer[1].len = len; |
172 | |
173 | spi_message_add_tail(t: &transfer[0], m: &msg); |
174 | spi_message_add_tail(t: &transfer[1], m: &msg); |
175 | ret = spi_sync(spi: qca->spi_dev, message: &msg); |
176 | |
177 | if (ret || (msg.actual_length != QCASPI_CMD_LEN + len)) { |
178 | qcaspi_spi_error(qca); |
179 | return 0; |
180 | } |
181 | |
182 | return len; |
183 | } |
184 | |
185 | static u32 |
186 | qcaspi_read_legacy(struct qcaspi *qca, u8 *dst, u32 len) |
187 | { |
188 | struct spi_message msg; |
189 | struct spi_transfer transfer; |
190 | int ret; |
191 | |
192 | memset(&transfer, 0, sizeof(transfer)); |
193 | spi_message_init(m: &msg); |
194 | |
195 | transfer.rx_buf = dst; |
196 | transfer.len = len; |
197 | |
198 | spi_message_add_tail(t: &transfer, m: &msg); |
199 | ret = spi_sync(spi: qca->spi_dev, message: &msg); |
200 | |
201 | if (ret || (msg.actual_length != len)) { |
202 | qcaspi_spi_error(qca); |
203 | return 0; |
204 | } |
205 | |
206 | return len; |
207 | } |
208 | |
209 | static int |
210 | qcaspi_tx_cmd(struct qcaspi *qca, u16 cmd) |
211 | { |
212 | __be16 tx_data; |
213 | struct spi_message msg; |
214 | struct spi_transfer transfer; |
215 | int ret; |
216 | |
217 | memset(&transfer, 0, sizeof(transfer)); |
218 | |
219 | spi_message_init(m: &msg); |
220 | |
221 | tx_data = cpu_to_be16(cmd); |
222 | transfer.len = sizeof(cmd); |
223 | transfer.tx_buf = &tx_data; |
224 | spi_message_add_tail(t: &transfer, m: &msg); |
225 | |
226 | ret = spi_sync(spi: qca->spi_dev, message: &msg); |
227 | |
228 | if (!ret) |
229 | ret = msg.status; |
230 | |
231 | if (ret) |
232 | qcaspi_spi_error(qca); |
233 | |
234 | return ret; |
235 | } |
236 | |
237 | static int |
238 | qcaspi_tx_frame(struct qcaspi *qca, struct sk_buff *skb) |
239 | { |
240 | u32 count; |
241 | u32 written; |
242 | u32 offset; |
243 | u32 len; |
244 | |
245 | len = skb->len; |
246 | |
247 | qcaspi_write_register(qca, SPI_REG_BFR_SIZE, value: len, retry: wr_verify); |
248 | if (qca->legacy_mode) |
249 | qcaspi_tx_cmd(qca, QCA7K_SPI_WRITE | QCA7K_SPI_EXTERNAL); |
250 | |
251 | offset = 0; |
252 | while (len) { |
253 | count = len; |
254 | if (count > qca->burst_len) |
255 | count = qca->burst_len; |
256 | |
257 | if (qca->legacy_mode) { |
258 | written = qcaspi_write_legacy(qca, |
259 | src: skb->data + offset, |
260 | len: count); |
261 | } else { |
262 | written = qcaspi_write_burst(qca, |
263 | src: skb->data + offset, |
264 | len: count); |
265 | } |
266 | |
267 | if (written != count) |
268 | return -1; |
269 | |
270 | offset += count; |
271 | len -= count; |
272 | } |
273 | |
274 | return 0; |
275 | } |
276 | |
277 | static int |
278 | qcaspi_transmit(struct qcaspi *qca) |
279 | { |
280 | struct net_device_stats *n_stats = &qca->net_dev->stats; |
281 | u16 available = 0; |
282 | u32 pkt_len; |
283 | u16 new_head; |
284 | u16 packets = 0; |
285 | |
286 | if (qca->txr.skb[qca->txr.head] == NULL) |
287 | return 0; |
288 | |
289 | qcaspi_read_register(qca, SPI_REG_WRBUF_SPC_AVA, result: &available); |
290 | |
291 | if (available > QCASPI_HW_BUF_LEN) { |
292 | /* This could only happen by interferences on the SPI line. |
293 | * So retry later ... |
294 | */ |
295 | qca->stats.buf_avail_err++; |
296 | return -1; |
297 | } |
298 | |
299 | while (qca->txr.skb[qca->txr.head]) { |
300 | pkt_len = qca->txr.skb[qca->txr.head]->len + QCASPI_HW_PKT_LEN; |
301 | |
302 | if (available < pkt_len) { |
303 | if (packets == 0) |
304 | qca->stats.write_buf_miss++; |
305 | break; |
306 | } |
307 | |
308 | if (qcaspi_tx_frame(qca, skb: qca->txr.skb[qca->txr.head]) == -1) { |
309 | qca->stats.write_err++; |
310 | return -1; |
311 | } |
312 | |
313 | packets++; |
314 | n_stats->tx_packets++; |
315 | n_stats->tx_bytes += qca->txr.skb[qca->txr.head]->len; |
316 | available -= pkt_len; |
317 | |
318 | /* remove the skb from the queue */ |
319 | /* XXX After inconsistent lock states netif_tx_lock() |
320 | * has been replaced by netif_tx_lock_bh() and so on. |
321 | */ |
322 | netif_tx_lock_bh(dev: qca->net_dev); |
323 | dev_kfree_skb(qca->txr.skb[qca->txr.head]); |
324 | qca->txr.skb[qca->txr.head] = NULL; |
325 | qca->txr.size -= pkt_len; |
326 | new_head = qca->txr.head + 1; |
327 | if (new_head >= qca->txr.count) |
328 | new_head = 0; |
329 | qca->txr.head = new_head; |
330 | if (netif_queue_stopped(dev: qca->net_dev)) |
331 | netif_wake_queue(dev: qca->net_dev); |
332 | netif_tx_unlock_bh(dev: qca->net_dev); |
333 | } |
334 | |
335 | return 0; |
336 | } |
337 | |
338 | static int |
339 | qcaspi_receive(struct qcaspi *qca) |
340 | { |
341 | struct net_device *net_dev = qca->net_dev; |
342 | struct net_device_stats *n_stats = &net_dev->stats; |
343 | u16 available = 0; |
344 | u32 bytes_read; |
345 | u8 *cp; |
346 | |
347 | /* Allocate rx SKB if we don't have one available. */ |
348 | if (!qca->rx_skb) { |
349 | qca->rx_skb = netdev_alloc_skb_ip_align(dev: net_dev, |
350 | length: net_dev->mtu + |
351 | VLAN_ETH_HLEN); |
352 | if (!qca->rx_skb) { |
353 | netdev_dbg(net_dev, "out of RX resources\n" ); |
354 | qca->stats.out_of_mem++; |
355 | return -1; |
356 | } |
357 | } |
358 | |
359 | /* Read the packet size. */ |
360 | qcaspi_read_register(qca, SPI_REG_RDBUF_BYTE_AVA, result: &available); |
361 | |
362 | netdev_dbg(net_dev, "qcaspi_receive: SPI_REG_RDBUF_BYTE_AVA: Value: %08x\n" , |
363 | available); |
364 | |
365 | if (available > QCASPI_HW_BUF_LEN + QCASPI_HW_PKT_LEN) { |
366 | /* This could only happen by interferences on the SPI line. |
367 | * So retry later ... |
368 | */ |
369 | qca->stats.buf_avail_err++; |
370 | return -1; |
371 | } else if (available == 0) { |
372 | netdev_dbg(net_dev, "qcaspi_receive called without any data being available!\n" ); |
373 | return -1; |
374 | } |
375 | |
376 | qcaspi_write_register(qca, SPI_REG_BFR_SIZE, value: available, retry: wr_verify); |
377 | |
378 | if (qca->legacy_mode) |
379 | qcaspi_tx_cmd(qca, QCA7K_SPI_READ | QCA7K_SPI_EXTERNAL); |
380 | |
381 | while (available) { |
382 | u32 count = available; |
383 | |
384 | if (count > qca->burst_len) |
385 | count = qca->burst_len; |
386 | |
387 | if (qca->legacy_mode) { |
388 | bytes_read = qcaspi_read_legacy(qca, dst: qca->rx_buffer, |
389 | len: count); |
390 | } else { |
391 | bytes_read = qcaspi_read_burst(qca, dst: qca->rx_buffer, |
392 | len: count); |
393 | } |
394 | |
395 | netdev_dbg(net_dev, "available: %d, byte read: %d\n" , |
396 | available, bytes_read); |
397 | |
398 | if (bytes_read) { |
399 | available -= bytes_read; |
400 | } else { |
401 | qca->stats.read_err++; |
402 | return -1; |
403 | } |
404 | |
405 | cp = qca->rx_buffer; |
406 | |
407 | while ((bytes_read--) && (qca->rx_skb)) { |
408 | s32 retcode; |
409 | |
410 | retcode = qcafrm_fsm_decode(handle: &qca->frm_handle, |
411 | buf: qca->rx_skb->data, |
412 | buf_len: skb_tailroom(skb: qca->rx_skb), |
413 | recv_byte: *cp); |
414 | cp++; |
415 | switch (retcode) { |
416 | case QCAFRM_GATHER: |
417 | case QCAFRM_NOHEAD: |
418 | break; |
419 | case QCAFRM_NOTAIL: |
420 | netdev_dbg(net_dev, "no RX tail\n" ); |
421 | n_stats->rx_errors++; |
422 | n_stats->rx_dropped++; |
423 | break; |
424 | case QCAFRM_INVLEN: |
425 | netdev_dbg(net_dev, "invalid RX length\n" ); |
426 | n_stats->rx_errors++; |
427 | n_stats->rx_dropped++; |
428 | break; |
429 | default: |
430 | qca->rx_skb->dev = qca->net_dev; |
431 | n_stats->rx_packets++; |
432 | n_stats->rx_bytes += retcode; |
433 | skb_put(skb: qca->rx_skb, len: retcode); |
434 | qca->rx_skb->protocol = eth_type_trans( |
435 | skb: qca->rx_skb, dev: qca->rx_skb->dev); |
436 | skb_checksum_none_assert(skb: qca->rx_skb); |
437 | netif_rx(skb: qca->rx_skb); |
438 | qca->rx_skb = netdev_alloc_skb_ip_align(dev: net_dev, |
439 | length: net_dev->mtu + VLAN_ETH_HLEN); |
440 | if (!qca->rx_skb) { |
441 | netdev_dbg(net_dev, "out of RX resources\n" ); |
442 | n_stats->rx_errors++; |
443 | qca->stats.out_of_mem++; |
444 | break; |
445 | } |
446 | } |
447 | } |
448 | } |
449 | |
450 | return 0; |
451 | } |
452 | |
453 | /* Check that tx ring stores only so much bytes |
454 | * that fit into the internal QCA buffer. |
455 | */ |
456 | |
457 | static int |
458 | qcaspi_tx_ring_has_space(struct tx_ring *txr) |
459 | { |
460 | if (txr->skb[txr->tail]) |
461 | return 0; |
462 | |
463 | return (txr->size + QCAFRM_MAX_LEN < QCASPI_HW_BUF_LEN) ? 1 : 0; |
464 | } |
465 | |
466 | /* Flush the tx ring. This function is only safe to |
467 | * call from the qcaspi_spi_thread. |
468 | */ |
469 | |
470 | static void |
471 | qcaspi_flush_tx_ring(struct qcaspi *qca) |
472 | { |
473 | int i; |
474 | |
475 | /* XXX After inconsistent lock states netif_tx_lock() |
476 | * has been replaced by netif_tx_lock_bh() and so on. |
477 | */ |
478 | netif_tx_lock_bh(dev: qca->net_dev); |
479 | for (i = 0; i < TX_RING_MAX_LEN; i++) { |
480 | if (qca->txr.skb[i]) { |
481 | dev_kfree_skb(qca->txr.skb[i]); |
482 | qca->txr.skb[i] = NULL; |
483 | qca->net_dev->stats.tx_dropped++; |
484 | } |
485 | } |
486 | qca->txr.tail = 0; |
487 | qca->txr.head = 0; |
488 | qca->txr.size = 0; |
489 | netif_tx_unlock_bh(dev: qca->net_dev); |
490 | } |
491 | |
492 | static void |
493 | qcaspi_qca7k_sync(struct qcaspi *qca, int event) |
494 | { |
495 | u16 signature = 0; |
496 | u16 spi_config; |
497 | u16 wrbuf_space = 0; |
498 | |
499 | if (event == QCASPI_EVENT_CPUON) { |
500 | /* Read signature twice, if not valid |
501 | * go back to unknown state. |
502 | */ |
503 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
504 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
505 | if (signature != QCASPI_GOOD_SIGNATURE) { |
506 | if (qca->sync == QCASPI_SYNC_READY) |
507 | qca->stats.bad_signature++; |
508 | |
509 | qca->sync = QCASPI_SYNC_UNKNOWN; |
510 | netdev_dbg(qca->net_dev, "sync: got CPU on, but signature was invalid, restart\n" ); |
511 | return; |
512 | } else { |
513 | /* ensure that the WRBUF is empty */ |
514 | qcaspi_read_register(qca, SPI_REG_WRBUF_SPC_AVA, |
515 | result: &wrbuf_space); |
516 | if (wrbuf_space != QCASPI_HW_BUF_LEN) { |
517 | netdev_dbg(qca->net_dev, "sync: got CPU on, but wrbuf not empty. reset!\n" ); |
518 | qca->sync = QCASPI_SYNC_UNKNOWN; |
519 | } else { |
520 | netdev_dbg(qca->net_dev, "sync: got CPU on, now in sync\n" ); |
521 | qca->sync = QCASPI_SYNC_READY; |
522 | return; |
523 | } |
524 | } |
525 | } |
526 | |
527 | switch (qca->sync) { |
528 | case QCASPI_SYNC_READY: |
529 | /* Check signature twice, if not valid go to unknown state. */ |
530 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
531 | if (signature != QCASPI_GOOD_SIGNATURE) |
532 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
533 | |
534 | if (signature != QCASPI_GOOD_SIGNATURE) { |
535 | qca->sync = QCASPI_SYNC_UNKNOWN; |
536 | qca->stats.bad_signature++; |
537 | netdev_dbg(qca->net_dev, "sync: bad signature, restart\n" ); |
538 | /* don't reset right away */ |
539 | return; |
540 | } |
541 | break; |
542 | case QCASPI_SYNC_UNKNOWN: |
543 | /* Read signature, if not valid stay in unknown state */ |
544 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
545 | if (signature != QCASPI_GOOD_SIGNATURE) { |
546 | netdev_dbg(qca->net_dev, "sync: could not read signature to reset device, retry.\n" ); |
547 | return; |
548 | } |
549 | |
550 | /* TODO: use GPIO to reset QCA7000 in legacy mode*/ |
551 | netdev_dbg(qca->net_dev, "sync: resetting device.\n" ); |
552 | qcaspi_read_register(qca, SPI_REG_SPI_CONFIG, result: &spi_config); |
553 | spi_config |= QCASPI_SLAVE_RESET_BIT; |
554 | qcaspi_write_register(qca, SPI_REG_SPI_CONFIG, value: spi_config, retry: 0); |
555 | |
556 | qca->sync = QCASPI_SYNC_RESET; |
557 | qca->stats.trig_reset++; |
558 | qca->reset_count = 0; |
559 | break; |
560 | case QCASPI_SYNC_RESET: |
561 | qca->reset_count++; |
562 | netdev_dbg(qca->net_dev, "sync: waiting for CPU on, count %u.\n" , |
563 | qca->reset_count); |
564 | if (qca->reset_count >= QCASPI_RESET_TIMEOUT) { |
565 | /* reset did not seem to take place, try again */ |
566 | qca->sync = QCASPI_SYNC_UNKNOWN; |
567 | qca->stats.reset_timeout++; |
568 | netdev_dbg(qca->net_dev, "sync: reset timeout, restarting process.\n" ); |
569 | } |
570 | break; |
571 | } |
572 | } |
573 | |
574 | static int |
575 | qcaspi_spi_thread(void *data) |
576 | { |
577 | struct qcaspi *qca = data; |
578 | u16 intr_cause = 0; |
579 | |
580 | netdev_info(dev: qca->net_dev, format: "SPI thread created\n" ); |
581 | while (!kthread_should_stop()) { |
582 | set_current_state(TASK_INTERRUPTIBLE); |
583 | if ((qca->intr_req == qca->intr_svc) && |
584 | !qca->txr.skb[qca->txr.head]) |
585 | schedule(); |
586 | |
587 | set_current_state(TASK_RUNNING); |
588 | |
589 | netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n" , |
590 | qca->intr_req - qca->intr_svc, |
591 | qca->txr.skb[qca->txr.head]); |
592 | |
593 | qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE); |
594 | |
595 | if (qca->sync != QCASPI_SYNC_READY) { |
596 | netdev_dbg(qca->net_dev, "sync: not ready %u, turn off carrier and flush\n" , |
597 | (unsigned int)qca->sync); |
598 | netif_stop_queue(dev: qca->net_dev); |
599 | netif_carrier_off(dev: qca->net_dev); |
600 | qcaspi_flush_tx_ring(qca); |
601 | msleep(QCASPI_QCA7K_REBOOT_TIME_MS); |
602 | } |
603 | |
604 | if (qca->intr_svc != qca->intr_req) { |
605 | qca->intr_svc = qca->intr_req; |
606 | start_spi_intr_handling(qca, intr_cause: &intr_cause); |
607 | |
608 | if (intr_cause & SPI_INT_CPU_ON) { |
609 | qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON); |
610 | |
611 | /* not synced. */ |
612 | if (qca->sync != QCASPI_SYNC_READY) |
613 | continue; |
614 | |
615 | qca->stats.device_reset++; |
616 | netif_wake_queue(dev: qca->net_dev); |
617 | netif_carrier_on(dev: qca->net_dev); |
618 | } |
619 | |
620 | if (intr_cause & SPI_INT_RDBUF_ERR) { |
621 | /* restart sync */ |
622 | netdev_dbg(qca->net_dev, "===> rdbuf error!\n" ); |
623 | qca->stats.read_buf_err++; |
624 | qca->sync = QCASPI_SYNC_UNKNOWN; |
625 | continue; |
626 | } |
627 | |
628 | if (intr_cause & SPI_INT_WRBUF_ERR) { |
629 | /* restart sync */ |
630 | netdev_dbg(qca->net_dev, "===> wrbuf error!\n" ); |
631 | qca->stats.write_buf_err++; |
632 | qca->sync = QCASPI_SYNC_UNKNOWN; |
633 | continue; |
634 | } |
635 | |
636 | /* can only handle other interrupts |
637 | * if sync has occurred |
638 | */ |
639 | if (qca->sync == QCASPI_SYNC_READY) { |
640 | if (intr_cause & SPI_INT_PKT_AVLBL) |
641 | qcaspi_receive(qca); |
642 | } |
643 | |
644 | end_spi_intr_handling(qca, intr_cause); |
645 | } |
646 | |
647 | if (qca->sync == QCASPI_SYNC_READY) |
648 | qcaspi_transmit(qca); |
649 | } |
650 | set_current_state(TASK_RUNNING); |
651 | netdev_info(dev: qca->net_dev, format: "SPI thread exit\n" ); |
652 | |
653 | return 0; |
654 | } |
655 | |
656 | static irqreturn_t |
657 | qcaspi_intr_handler(int irq, void *data) |
658 | { |
659 | struct qcaspi *qca = data; |
660 | |
661 | qca->intr_req++; |
662 | if (qca->spi_thread) |
663 | wake_up_process(tsk: qca->spi_thread); |
664 | |
665 | return IRQ_HANDLED; |
666 | } |
667 | |
668 | static int |
669 | qcaspi_netdev_open(struct net_device *dev) |
670 | { |
671 | struct qcaspi *qca = netdev_priv(dev); |
672 | int ret = 0; |
673 | |
674 | if (!qca) |
675 | return -EINVAL; |
676 | |
677 | qca->intr_req = 1; |
678 | qca->intr_svc = 0; |
679 | qca->sync = QCASPI_SYNC_UNKNOWN; |
680 | qcafrm_fsm_init_spi(handle: &qca->frm_handle); |
681 | |
682 | qca->spi_thread = kthread_run((void *)qcaspi_spi_thread, |
683 | qca, "%s" , dev->name); |
684 | |
685 | if (IS_ERR(ptr: qca->spi_thread)) { |
686 | netdev_err(dev, format: "%s: unable to start kernel thread.\n" , |
687 | QCASPI_DRV_NAME); |
688 | return PTR_ERR(ptr: qca->spi_thread); |
689 | } |
690 | |
691 | ret = request_irq(irq: qca->spi_dev->irq, handler: qcaspi_intr_handler, flags: 0, |
692 | name: dev->name, dev: qca); |
693 | if (ret) { |
694 | netdev_err(dev, format: "%s: unable to get IRQ %d (irqval=%d).\n" , |
695 | QCASPI_DRV_NAME, qca->spi_dev->irq, ret); |
696 | kthread_stop(k: qca->spi_thread); |
697 | return ret; |
698 | } |
699 | |
700 | /* SPI thread takes care of TX queue */ |
701 | |
702 | return 0; |
703 | } |
704 | |
705 | static int |
706 | qcaspi_netdev_close(struct net_device *dev) |
707 | { |
708 | struct qcaspi *qca = netdev_priv(dev); |
709 | |
710 | netif_stop_queue(dev); |
711 | |
712 | qcaspi_write_register(qca, SPI_REG_INTR_ENABLE, value: 0, retry: wr_verify); |
713 | free_irq(qca->spi_dev->irq, qca); |
714 | |
715 | kthread_stop(k: qca->spi_thread); |
716 | qca->spi_thread = NULL; |
717 | qcaspi_flush_tx_ring(qca); |
718 | |
719 | return 0; |
720 | } |
721 | |
722 | static netdev_tx_t |
723 | qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev) |
724 | { |
725 | u32 frame_len; |
726 | u8 *ptmp; |
727 | struct qcaspi *qca = netdev_priv(dev); |
728 | u16 new_tail; |
729 | struct sk_buff *tskb; |
730 | u8 pad_len = 0; |
731 | |
732 | if (skb->len < QCAFRM_MIN_LEN) |
733 | pad_len = QCAFRM_MIN_LEN - skb->len; |
734 | |
735 | if (qca->txr.skb[qca->txr.tail]) { |
736 | netdev_warn(dev: qca->net_dev, format: "queue was unexpectedly full!\n" ); |
737 | netif_stop_queue(dev: qca->net_dev); |
738 | qca->stats.ring_full++; |
739 | return NETDEV_TX_BUSY; |
740 | } |
741 | |
742 | if ((skb_headroom(skb) < QCAFRM_HEADER_LEN) || |
743 | (skb_tailroom(skb) < QCAFRM_FOOTER_LEN + pad_len)) { |
744 | tskb = skb_copy_expand(skb, QCAFRM_HEADER_LEN, |
745 | QCAFRM_FOOTER_LEN + pad_len, GFP_ATOMIC); |
746 | if (!tskb) { |
747 | qca->stats.out_of_mem++; |
748 | return NETDEV_TX_BUSY; |
749 | } |
750 | dev_kfree_skb(skb); |
751 | skb = tskb; |
752 | } |
753 | |
754 | frame_len = skb->len + pad_len; |
755 | |
756 | ptmp = skb_push(skb, QCAFRM_HEADER_LEN); |
757 | qcafrm_create_header(buf: ptmp, len: frame_len); |
758 | |
759 | if (pad_len) { |
760 | ptmp = skb_put_zero(skb, len: pad_len); |
761 | } |
762 | |
763 | ptmp = skb_put(skb, QCAFRM_FOOTER_LEN); |
764 | qcafrm_create_footer(buf: ptmp); |
765 | |
766 | netdev_dbg(qca->net_dev, "Tx-ing packet: Size: 0x%08x\n" , |
767 | skb->len); |
768 | |
769 | qca->txr.size += skb->len + QCASPI_HW_PKT_LEN; |
770 | |
771 | new_tail = qca->txr.tail + 1; |
772 | if (new_tail >= qca->txr.count) |
773 | new_tail = 0; |
774 | |
775 | qca->txr.skb[qca->txr.tail] = skb; |
776 | qca->txr.tail = new_tail; |
777 | |
778 | if (!qcaspi_tx_ring_has_space(txr: &qca->txr)) { |
779 | netif_stop_queue(dev: qca->net_dev); |
780 | qca->stats.ring_full++; |
781 | } |
782 | |
783 | netif_trans_update(dev); |
784 | |
785 | if (qca->spi_thread) |
786 | wake_up_process(tsk: qca->spi_thread); |
787 | |
788 | return NETDEV_TX_OK; |
789 | } |
790 | |
791 | static void |
792 | qcaspi_netdev_tx_timeout(struct net_device *dev, unsigned int txqueue) |
793 | { |
794 | struct qcaspi *qca = netdev_priv(dev); |
795 | |
796 | netdev_info(dev: qca->net_dev, format: "Transmit timeout at %ld, latency %ld\n" , |
797 | jiffies, jiffies - dev_trans_start(dev)); |
798 | qca->net_dev->stats.tx_errors++; |
799 | /* Trigger tx queue flush and QCA7000 reset */ |
800 | qca->sync = QCASPI_SYNC_UNKNOWN; |
801 | |
802 | if (qca->spi_thread) |
803 | wake_up_process(tsk: qca->spi_thread); |
804 | } |
805 | |
806 | static int |
807 | qcaspi_netdev_init(struct net_device *dev) |
808 | { |
809 | struct qcaspi *qca = netdev_priv(dev); |
810 | |
811 | dev->mtu = QCAFRM_MAX_MTU; |
812 | dev->type = ARPHRD_ETHER; |
813 | qca->clkspeed = qcaspi_clkspeed; |
814 | qca->burst_len = qcaspi_burst_len; |
815 | qca->spi_thread = NULL; |
816 | qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN + |
817 | QCAFRM_FOOTER_LEN + 4) * 4; |
818 | |
819 | memset(&qca->stats, 0, sizeof(struct qcaspi_stats)); |
820 | |
821 | qca->rx_buffer = kmalloc(size: qca->buffer_size, GFP_KERNEL); |
822 | if (!qca->rx_buffer) |
823 | return -ENOBUFS; |
824 | |
825 | qca->rx_skb = netdev_alloc_skb_ip_align(dev, length: qca->net_dev->mtu + |
826 | VLAN_ETH_HLEN); |
827 | if (!qca->rx_skb) { |
828 | kfree(objp: qca->rx_buffer); |
829 | netdev_info(dev: qca->net_dev, format: "Failed to allocate RX sk_buff.\n" ); |
830 | return -ENOBUFS; |
831 | } |
832 | |
833 | return 0; |
834 | } |
835 | |
836 | static void |
837 | qcaspi_netdev_uninit(struct net_device *dev) |
838 | { |
839 | struct qcaspi *qca = netdev_priv(dev); |
840 | |
841 | kfree(objp: qca->rx_buffer); |
842 | qca->buffer_size = 0; |
843 | dev_kfree_skb(qca->rx_skb); |
844 | } |
845 | |
846 | static const struct net_device_ops qcaspi_netdev_ops = { |
847 | .ndo_init = qcaspi_netdev_init, |
848 | .ndo_uninit = qcaspi_netdev_uninit, |
849 | .ndo_open = qcaspi_netdev_open, |
850 | .ndo_stop = qcaspi_netdev_close, |
851 | .ndo_start_xmit = qcaspi_netdev_xmit, |
852 | .ndo_set_mac_address = eth_mac_addr, |
853 | .ndo_tx_timeout = qcaspi_netdev_tx_timeout, |
854 | .ndo_validate_addr = eth_validate_addr, |
855 | }; |
856 | |
857 | static void |
858 | qcaspi_netdev_setup(struct net_device *dev) |
859 | { |
860 | struct qcaspi *qca = NULL; |
861 | |
862 | dev->netdev_ops = &qcaspi_netdev_ops; |
863 | qcaspi_set_ethtool_ops(dev); |
864 | dev->watchdog_timeo = QCASPI_TX_TIMEOUT; |
865 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
866 | dev->tx_queue_len = 100; |
867 | |
868 | /* MTU range: 46 - 1500 */ |
869 | dev->min_mtu = QCAFRM_MIN_MTU; |
870 | dev->max_mtu = QCAFRM_MAX_MTU; |
871 | |
872 | qca = netdev_priv(dev); |
873 | memset(qca, 0, sizeof(struct qcaspi)); |
874 | |
875 | memset(&qca->txr, 0, sizeof(qca->txr)); |
876 | qca->txr.count = TX_RING_MAX_LEN; |
877 | } |
878 | |
879 | static const struct of_device_id qca_spi_of_match[] = { |
880 | { .compatible = "qca,qca7000" }, |
881 | { /* sentinel */ } |
882 | }; |
883 | MODULE_DEVICE_TABLE(of, qca_spi_of_match); |
884 | |
885 | static int |
886 | qca_spi_probe(struct spi_device *spi) |
887 | { |
888 | struct qcaspi *qca = NULL; |
889 | struct net_device *qcaspi_devs = NULL; |
890 | u8 legacy_mode = 0; |
891 | u16 signature; |
892 | int ret; |
893 | |
894 | if (!spi->dev.of_node) { |
895 | dev_err(&spi->dev, "Missing device tree\n" ); |
896 | return -EINVAL; |
897 | } |
898 | |
899 | legacy_mode = of_property_read_bool(np: spi->dev.of_node, |
900 | propname: "qca,legacy-mode" ); |
901 | |
902 | if (qcaspi_clkspeed == 0) { |
903 | if (spi->max_speed_hz) |
904 | qcaspi_clkspeed = spi->max_speed_hz; |
905 | else |
906 | qcaspi_clkspeed = QCASPI_CLK_SPEED; |
907 | } |
908 | |
909 | if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) || |
910 | (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) { |
911 | dev_err(&spi->dev, "Invalid clkspeed: %d\n" , |
912 | qcaspi_clkspeed); |
913 | return -EINVAL; |
914 | } |
915 | |
916 | if ((qcaspi_burst_len < QCASPI_BURST_LEN_MIN) || |
917 | (qcaspi_burst_len > QCASPI_BURST_LEN_MAX)) { |
918 | dev_err(&spi->dev, "Invalid burst len: %d\n" , |
919 | qcaspi_burst_len); |
920 | return -EINVAL; |
921 | } |
922 | |
923 | if ((qcaspi_pluggable < QCASPI_PLUGGABLE_MIN) || |
924 | (qcaspi_pluggable > QCASPI_PLUGGABLE_MAX)) { |
925 | dev_err(&spi->dev, "Invalid pluggable: %d\n" , |
926 | qcaspi_pluggable); |
927 | return -EINVAL; |
928 | } |
929 | |
930 | if (wr_verify < QCASPI_WRITE_VERIFY_MIN || |
931 | wr_verify > QCASPI_WRITE_VERIFY_MAX) { |
932 | dev_err(&spi->dev, "Invalid write verify: %d\n" , |
933 | wr_verify); |
934 | return -EINVAL; |
935 | } |
936 | |
937 | dev_info(&spi->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n" , |
938 | QCASPI_DRV_VERSION, |
939 | qcaspi_clkspeed, |
940 | qcaspi_burst_len, |
941 | qcaspi_pluggable); |
942 | |
943 | spi->mode = SPI_MODE_3; |
944 | spi->max_speed_hz = qcaspi_clkspeed; |
945 | if (spi_setup(spi) < 0) { |
946 | dev_err(&spi->dev, "Unable to setup SPI device\n" ); |
947 | return -EFAULT; |
948 | } |
949 | |
950 | qcaspi_devs = alloc_etherdev(sizeof(struct qcaspi)); |
951 | if (!qcaspi_devs) |
952 | return -ENOMEM; |
953 | |
954 | qcaspi_netdev_setup(dev: qcaspi_devs); |
955 | SET_NETDEV_DEV(qcaspi_devs, &spi->dev); |
956 | |
957 | qca = netdev_priv(dev: qcaspi_devs); |
958 | if (!qca) { |
959 | free_netdev(dev: qcaspi_devs); |
960 | dev_err(&spi->dev, "Fail to retrieve private structure\n" ); |
961 | return -ENOMEM; |
962 | } |
963 | qca->net_dev = qcaspi_devs; |
964 | qca->spi_dev = spi; |
965 | qca->legacy_mode = legacy_mode; |
966 | |
967 | spi_set_drvdata(spi, data: qcaspi_devs); |
968 | |
969 | ret = of_get_ethdev_address(np: spi->dev.of_node, dev: qca->net_dev); |
970 | if (ret) { |
971 | eth_hw_addr_random(dev: qca->net_dev); |
972 | dev_info(&spi->dev, "Using random MAC address: %pM\n" , |
973 | qca->net_dev->dev_addr); |
974 | } |
975 | |
976 | netif_carrier_off(dev: qca->net_dev); |
977 | |
978 | if (!qcaspi_pluggable) { |
979 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
980 | qcaspi_read_register(qca, SPI_REG_SIGNATURE, result: &signature); |
981 | |
982 | if (signature != QCASPI_GOOD_SIGNATURE) { |
983 | dev_err(&spi->dev, "Invalid signature (0x%04X)\n" , |
984 | signature); |
985 | free_netdev(dev: qcaspi_devs); |
986 | return -EFAULT; |
987 | } |
988 | } |
989 | |
990 | if (register_netdev(dev: qcaspi_devs)) { |
991 | dev_err(&spi->dev, "Unable to register net device %s\n" , |
992 | qcaspi_devs->name); |
993 | free_netdev(dev: qcaspi_devs); |
994 | return -EFAULT; |
995 | } |
996 | |
997 | qcaspi_init_device_debugfs(qca); |
998 | |
999 | return 0; |
1000 | } |
1001 | |
1002 | static void |
1003 | qca_spi_remove(struct spi_device *spi) |
1004 | { |
1005 | struct net_device *qcaspi_devs = spi_get_drvdata(spi); |
1006 | struct qcaspi *qca = netdev_priv(dev: qcaspi_devs); |
1007 | |
1008 | qcaspi_remove_device_debugfs(qca); |
1009 | |
1010 | unregister_netdev(dev: qcaspi_devs); |
1011 | free_netdev(dev: qcaspi_devs); |
1012 | } |
1013 | |
1014 | static const struct spi_device_id qca_spi_id[] = { |
1015 | { "qca7000" , 0 }, |
1016 | { /* sentinel */ } |
1017 | }; |
1018 | MODULE_DEVICE_TABLE(spi, qca_spi_id); |
1019 | |
1020 | static struct spi_driver qca_spi_driver = { |
1021 | .driver = { |
1022 | .name = QCASPI_DRV_NAME, |
1023 | .of_match_table = qca_spi_of_match, |
1024 | }, |
1025 | .id_table = qca_spi_id, |
1026 | .probe = qca_spi_probe, |
1027 | .remove = qca_spi_remove, |
1028 | }; |
1029 | module_spi_driver(qca_spi_driver); |
1030 | |
1031 | MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 SPI Driver" ); |
1032 | MODULE_AUTHOR("Qualcomm Atheros Communications" ); |
1033 | MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>" ); |
1034 | MODULE_LICENSE("Dual BSD/GPL" ); |
1035 | MODULE_VERSION(QCASPI_DRV_VERSION); |
1036 | |