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