1
2
3
4
5
6
7#include <linux/clk.h>
8#include <linux/spi/spi.h>
9#include <linux/crc7.h>
10#include <linux/crc-itu-t.h>
11
12#include "netdev.h"
13#include "cfg80211.h"
14
15static bool enable_crc7;
16module_param(enable_crc7, bool, 0644);
17MODULE_PARM_DESC(enable_crc7,
18 "Enable CRC7 checksum to protect command transfers\n"
19 "\t\t\tagainst corruption during the SPI transfer.\n"
20 "\t\t\tCommand transfers are short and the CPU-cycle cost\n"
21 "\t\t\tof enabling this is small.");
22
23static bool enable_crc16;
24module_param(enable_crc16, bool, 0644);
25MODULE_PARM_DESC(enable_crc16,
26 "Enable CRC16 checksum to protect data transfers\n"
27 "\t\t\tagainst corruption during the SPI transfer.\n"
28 "\t\t\tData transfers can be large and the CPU-cycle cost\n"
29 "\t\t\tof enabling this may be substantial.");
30
31
32
33
34
35
36
37
38
39#define WILC_SPI_RSP_HDR_EXTRA_DATA 8
40
41struct wilc_spi {
42 bool isinit;
43 bool probing_crc;
44 bool crc7_enabled;
45 bool crc16_enabled;
46};
47
48static const struct wilc_hif_func wilc_hif_spi;
49
50
51
52
53
54
55
56#define CMD_DMA_WRITE 0xc1
57#define CMD_DMA_READ 0xc2
58#define CMD_INTERNAL_WRITE 0xc3
59#define CMD_INTERNAL_READ 0xc4
60#define CMD_TERMINATE 0xc5
61#define CMD_REPEAT 0xc6
62#define CMD_DMA_EXT_WRITE 0xc7
63#define CMD_DMA_EXT_READ 0xc8
64#define CMD_SINGLE_WRITE 0xc9
65#define CMD_SINGLE_READ 0xca
66#define CMD_RESET 0xcf
67
68#define SPI_ENABLE_VMM_RETRY_LIMIT 2
69
70
71#define RSP_START_FIELD GENMASK(7, 4)
72#define RSP_TYPE_FIELD GENMASK(3, 0)
73
74
75#define RSP_START_TAG 0xc
76#define RSP_TYPE_FIRST_PACKET 0x1
77#define RSP_TYPE_INNER_PACKET 0x2
78#define RSP_TYPE_LAST_PACKET 0x3
79#define RSP_STATE_NO_ERROR 0x00
80
81#define PROTOCOL_REG_PKT_SZ_MASK GENMASK(6, 4)
82#define PROTOCOL_REG_CRC16_MASK GENMASK(3, 3)
83#define PROTOCOL_REG_CRC7_MASK GENMASK(2, 2)
84
85
86
87
88
89#define DATA_PKT_LOG_SZ_MIN 8
90#define DATA_PKT_LOG_SZ_MAX 13
91
92
93
94
95
96
97#define DATA_PKT_LOG_SZ DATA_PKT_LOG_SZ_MAX
98#define DATA_PKT_SZ (1 << DATA_PKT_LOG_SZ)
99
100#define USE_SPI_DMA 0
101
102#define WILC_SPI_COMMAND_STAT_SUCCESS 0
103#define WILC_GET_RESP_HDR_START(h) (((h) >> 4) & 0xf)
104
105struct wilc_spi_cmd {
106 u8 cmd_type;
107 union {
108 struct {
109 u8 addr[3];
110 u8 crc[];
111 } __packed simple_cmd;
112 struct {
113 u8 addr[3];
114 u8 size[2];
115 u8 crc[];
116 } __packed dma_cmd;
117 struct {
118 u8 addr[3];
119 u8 size[3];
120 u8 crc[];
121 } __packed dma_cmd_ext;
122 struct {
123 u8 addr[2];
124 __be32 data;
125 u8 crc[];
126 } __packed internal_w_cmd;
127 struct {
128 u8 addr[3];
129 __be32 data;
130 u8 crc[];
131 } __packed w_cmd;
132 } u;
133} __packed;
134
135struct wilc_spi_read_rsp_data {
136 u8 header;
137 u8 data[4];
138 u8 crc[];
139} __packed;
140
141struct wilc_spi_rsp_data {
142 u8 rsp_cmd_type;
143 u8 status;
144 u8 data[];
145} __packed;
146
147static int wilc_bus_probe(struct spi_device *spi)
148{
149 int ret;
150 struct wilc *wilc;
151 struct wilc_spi *spi_priv;
152
153 spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);
154 if (!spi_priv)
155 return -ENOMEM;
156
157 ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
158 if (ret)
159 goto free;
160
161 spi_set_drvdata(spi, wilc);
162 wilc->dev = &spi->dev;
163 wilc->bus_data = spi_priv;
164 wilc->dev_irq_num = spi->irq;
165
166 wilc->rtc_clk = devm_clk_get_optional(&spi->dev, "rtc");
167 if (IS_ERR(wilc->rtc_clk)) {
168 ret = PTR_ERR(wilc->rtc_clk);
169 goto netdev_cleanup;
170 }
171 clk_prepare_enable(wilc->rtc_clk);
172
173 return 0;
174
175netdev_cleanup:
176 wilc_netdev_cleanup(wilc);
177free:
178 kfree(spi_priv);
179 return ret;
180}
181
182static int wilc_bus_remove(struct spi_device *spi)
183{
184 struct wilc *wilc = spi_get_drvdata(spi);
185
186 clk_disable_unprepare(wilc->rtc_clk);
187 wilc_netdev_cleanup(wilc);
188
189 return 0;
190}
191
192static const struct of_device_id wilc_of_match[] = {
193 { .compatible = "microchip,wilc1000", },
194 { }
195};
196MODULE_DEVICE_TABLE(of, wilc_of_match);
197
198static struct spi_driver wilc_spi_driver = {
199 .driver = {
200 .name = MODALIAS,
201 .of_match_table = wilc_of_match,
202 },
203 .probe = wilc_bus_probe,
204 .remove = wilc_bus_remove,
205};
206module_spi_driver(wilc_spi_driver);
207MODULE_LICENSE("GPL");
208
209static int wilc_spi_tx(struct wilc *wilc, u8 *b, u32 len)
210{
211 struct spi_device *spi = to_spi_device(wilc->dev);
212 int ret;
213 struct spi_message msg;
214
215 if (len > 0 && b) {
216 struct spi_transfer tr = {
217 .tx_buf = b,
218 .len = len,
219 .delay = {
220 .value = 0,
221 .unit = SPI_DELAY_UNIT_USECS
222 },
223 };
224 char *r_buffer = kzalloc(len, GFP_KERNEL);
225
226 if (!r_buffer)
227 return -ENOMEM;
228
229 tr.rx_buf = r_buffer;
230 dev_dbg(&spi->dev, "Request writing %d bytes\n", len);
231
232 memset(&msg, 0, sizeof(msg));
233 spi_message_init(&msg);
234 msg.spi = spi;
235 msg.is_dma_mapped = USE_SPI_DMA;
236 spi_message_add_tail(&tr, &msg);
237
238 ret = spi_sync(spi, &msg);
239 if (ret < 0)
240 dev_err(&spi->dev, "SPI transaction failed\n");
241
242 kfree(r_buffer);
243 } else {
244 dev_err(&spi->dev,
245 "can't write data with the following length: %d\n",
246 len);
247 ret = -EINVAL;
248 }
249
250 return ret;
251}
252
253static int wilc_spi_rx(struct wilc *wilc, u8 *rb, u32 rlen)
254{
255 struct spi_device *spi = to_spi_device(wilc->dev);
256 int ret;
257
258 if (rlen > 0) {
259 struct spi_message msg;
260 struct spi_transfer tr = {
261 .rx_buf = rb,
262 .len = rlen,
263 .delay = {
264 .value = 0,
265 .unit = SPI_DELAY_UNIT_USECS
266 },
267
268 };
269 char *t_buffer = kzalloc(rlen, GFP_KERNEL);
270
271 if (!t_buffer)
272 return -ENOMEM;
273
274 tr.tx_buf = t_buffer;
275
276 memset(&msg, 0, sizeof(msg));
277 spi_message_init(&msg);
278 msg.spi = spi;
279 msg.is_dma_mapped = USE_SPI_DMA;
280 spi_message_add_tail(&tr, &msg);
281
282 ret = spi_sync(spi, &msg);
283 if (ret < 0)
284 dev_err(&spi->dev, "SPI transaction failed\n");
285 kfree(t_buffer);
286 } else {
287 dev_err(&spi->dev,
288 "can't read data with the following length: %u\n",
289 rlen);
290 ret = -EINVAL;
291 }
292
293 return ret;
294}
295
296static int wilc_spi_tx_rx(struct wilc *wilc, u8 *wb, u8 *rb, u32 rlen)
297{
298 struct spi_device *spi = to_spi_device(wilc->dev);
299 int ret;
300
301 if (rlen > 0) {
302 struct spi_message msg;
303 struct spi_transfer tr = {
304 .rx_buf = rb,
305 .tx_buf = wb,
306 .len = rlen,
307 .bits_per_word = 8,
308 .delay = {
309 .value = 0,
310 .unit = SPI_DELAY_UNIT_USECS
311 },
312
313 };
314
315 memset(&msg, 0, sizeof(msg));
316 spi_message_init(&msg);
317 msg.spi = spi;
318 msg.is_dma_mapped = USE_SPI_DMA;
319
320 spi_message_add_tail(&tr, &msg);
321 ret = spi_sync(spi, &msg);
322 if (ret < 0)
323 dev_err(&spi->dev, "SPI transaction failed\n");
324 } else {
325 dev_err(&spi->dev,
326 "can't read data with the following length: %u\n",
327 rlen);
328 ret = -EINVAL;
329 }
330
331 return ret;
332}
333
334static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
335{
336 struct spi_device *spi = to_spi_device(wilc->dev);
337 struct wilc_spi *spi_priv = wilc->bus_data;
338 int ix, nbytes;
339 int result = 0;
340 u8 cmd, order, crc[2];
341 u16 crc_calc;
342
343
344
345
346 ix = 0;
347 do {
348 if (sz <= DATA_PKT_SZ) {
349 nbytes = sz;
350 order = 0x3;
351 } else {
352 nbytes = DATA_PKT_SZ;
353 if (ix == 0)
354 order = 0x1;
355 else
356 order = 0x02;
357 }
358
359
360
361
362 cmd = 0xf0;
363 cmd |= order;
364
365 if (wilc_spi_tx(wilc, &cmd, 1)) {
366 dev_err(&spi->dev,
367 "Failed data block cmd write, bus error...\n");
368 result = -EINVAL;
369 break;
370 }
371
372
373
374
375 if (wilc_spi_tx(wilc, &b[ix], nbytes)) {
376 dev_err(&spi->dev,
377 "Failed data block write, bus error...\n");
378 result = -EINVAL;
379 break;
380 }
381
382
383
384
385 if (spi_priv->crc16_enabled) {
386 crc_calc = crc_itu_t(0xffff, &b[ix], nbytes);
387 crc[0] = crc_calc >> 8;
388 crc[1] = crc_calc;
389 if (wilc_spi_tx(wilc, crc, 2)) {
390 dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
391 result = -EINVAL;
392 break;
393 }
394 }
395
396
397
398
399 ix += nbytes;
400 sz -= nbytes;
401 } while (sz);
402
403 return result;
404}
405
406
407
408
409
410
411static u8 wilc_get_crc7(u8 *buffer, u32 len)
412{
413 return crc7_be(0xfe, buffer, len);
414}
415
416static int wilc_spi_single_read(struct wilc *wilc, u8 cmd, u32 adr, void *b,
417 u8 clockless)
418{
419 struct spi_device *spi = to_spi_device(wilc->dev);
420 struct wilc_spi *spi_priv = wilc->bus_data;
421 u8 wb[32], rb[32];
422 int cmd_len, resp_len, i;
423 u16 crc_calc, crc_recv;
424 struct wilc_spi_cmd *c;
425 struct wilc_spi_rsp_data *r;
426 struct wilc_spi_read_rsp_data *r_data;
427
428 memset(wb, 0x0, sizeof(wb));
429 memset(rb, 0x0, sizeof(rb));
430 c = (struct wilc_spi_cmd *)wb;
431 c->cmd_type = cmd;
432 if (cmd == CMD_SINGLE_READ) {
433 c->u.simple_cmd.addr[0] = adr >> 16;
434 c->u.simple_cmd.addr[1] = adr >> 8;
435 c->u.simple_cmd.addr[2] = adr;
436 } else if (cmd == CMD_INTERNAL_READ) {
437 c->u.simple_cmd.addr[0] = adr >> 8;
438 if (clockless == 1)
439 c->u.simple_cmd.addr[0] |= BIT(7);
440 c->u.simple_cmd.addr[1] = adr;
441 c->u.simple_cmd.addr[2] = 0x0;
442 } else {
443 dev_err(&spi->dev, "cmd [%x] not supported\n", cmd);
444 return -EINVAL;
445 }
446
447 cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
448 resp_len = sizeof(*r) + sizeof(*r_data) + WILC_SPI_RSP_HDR_EXTRA_DATA;
449
450 if (spi_priv->crc7_enabled) {
451 c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
452 cmd_len += 1;
453 resp_len += 2;
454 }
455
456 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
457 dev_err(&spi->dev,
458 "spi buffer size too small (%d) (%d) (%zu)\n",
459 cmd_len, resp_len, ARRAY_SIZE(wb));
460 return -EINVAL;
461 }
462
463 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
464 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
465 return -EINVAL;
466 }
467
468 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
469 if (r->rsp_cmd_type != cmd) {
470 if (!spi_priv->probing_crc)
471 dev_err(&spi->dev,
472 "Failed cmd, cmd (%02x), resp (%02x)\n",
473 cmd, r->rsp_cmd_type);
474 return -EINVAL;
475 }
476
477 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
478 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
479 r->status);
480 return -EINVAL;
481 }
482
483 for (i = 0; i < WILC_SPI_RSP_HDR_EXTRA_DATA; ++i)
484 if (WILC_GET_RESP_HDR_START(r->data[i]) == 0xf)
485 break;
486
487 if (i >= WILC_SPI_RSP_HDR_EXTRA_DATA) {
488 dev_err(&spi->dev, "Error, data start missing\n");
489 return -EINVAL;
490 }
491
492 r_data = (struct wilc_spi_read_rsp_data *)&r->data[i];
493
494 if (b)
495 memcpy(b, r_data->data, 4);
496
497 if (!clockless && spi_priv->crc16_enabled) {
498 crc_recv = (r_data->crc[0] << 8) | r_data->crc[1];
499 crc_calc = crc_itu_t(0xffff, r_data->data, 4);
500 if (crc_recv != crc_calc) {
501 dev_err(&spi->dev, "%s: bad CRC 0x%04x "
502 "(calculated 0x%04x)\n", __func__,
503 crc_recv, crc_calc);
504 return -EINVAL;
505 }
506 }
507
508 return 0;
509}
510
511static int wilc_spi_write_cmd(struct wilc *wilc, u8 cmd, u32 adr, u32 data,
512 u8 clockless)
513{
514 struct spi_device *spi = to_spi_device(wilc->dev);
515 struct wilc_spi *spi_priv = wilc->bus_data;
516 u8 wb[32], rb[32];
517 int cmd_len, resp_len;
518 struct wilc_spi_cmd *c;
519 struct wilc_spi_rsp_data *r;
520
521 memset(wb, 0x0, sizeof(wb));
522 memset(rb, 0x0, sizeof(rb));
523 c = (struct wilc_spi_cmd *)wb;
524 c->cmd_type = cmd;
525 if (cmd == CMD_INTERNAL_WRITE) {
526 c->u.internal_w_cmd.addr[0] = adr >> 8;
527 if (clockless == 1)
528 c->u.internal_w_cmd.addr[0] |= BIT(7);
529
530 c->u.internal_w_cmd.addr[1] = adr;
531 c->u.internal_w_cmd.data = cpu_to_be32(data);
532 cmd_len = offsetof(struct wilc_spi_cmd, u.internal_w_cmd.crc);
533 if (spi_priv->crc7_enabled)
534 c->u.internal_w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
535 } else if (cmd == CMD_SINGLE_WRITE) {
536 c->u.w_cmd.addr[0] = adr >> 16;
537 c->u.w_cmd.addr[1] = adr >> 8;
538 c->u.w_cmd.addr[2] = adr;
539 c->u.w_cmd.data = cpu_to_be32(data);
540 cmd_len = offsetof(struct wilc_spi_cmd, u.w_cmd.crc);
541 if (spi_priv->crc7_enabled)
542 c->u.w_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
543 } else {
544 dev_err(&spi->dev, "write cmd [%x] not supported\n", cmd);
545 return -EINVAL;
546 }
547
548 if (spi_priv->crc7_enabled)
549 cmd_len += 1;
550
551 resp_len = sizeof(*r);
552
553 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
554 dev_err(&spi->dev,
555 "spi buffer size too small (%d) (%d) (%zu)\n",
556 cmd_len, resp_len, ARRAY_SIZE(wb));
557 return -EINVAL;
558 }
559
560 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
561 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
562 return -EINVAL;
563 }
564
565 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
566 if (r->rsp_cmd_type != cmd) {
567 dev_err(&spi->dev,
568 "Failed cmd response, cmd (%02x), resp (%02x)\n",
569 cmd, r->rsp_cmd_type);
570 return -EINVAL;
571 }
572
573 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
574 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
575 r->status);
576 return -EINVAL;
577 }
578
579 return 0;
580}
581
582static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
583{
584 struct spi_device *spi = to_spi_device(wilc->dev);
585 struct wilc_spi *spi_priv = wilc->bus_data;
586 u16 crc_recv, crc_calc;
587 u8 wb[32], rb[32];
588 int cmd_len, resp_len;
589 int retry, ix = 0;
590 u8 crc[2];
591 struct wilc_spi_cmd *c;
592 struct wilc_spi_rsp_data *r;
593
594 memset(wb, 0x0, sizeof(wb));
595 memset(rb, 0x0, sizeof(rb));
596 c = (struct wilc_spi_cmd *)wb;
597 c->cmd_type = cmd;
598 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_READ) {
599 c->u.dma_cmd.addr[0] = adr >> 16;
600 c->u.dma_cmd.addr[1] = adr >> 8;
601 c->u.dma_cmd.addr[2] = adr;
602 c->u.dma_cmd.size[0] = sz >> 8;
603 c->u.dma_cmd.size[1] = sz;
604 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd.crc);
605 if (spi_priv->crc7_enabled)
606 c->u.dma_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
607 } else if (cmd == CMD_DMA_EXT_WRITE || cmd == CMD_DMA_EXT_READ) {
608 c->u.dma_cmd_ext.addr[0] = adr >> 16;
609 c->u.dma_cmd_ext.addr[1] = adr >> 8;
610 c->u.dma_cmd_ext.addr[2] = adr;
611 c->u.dma_cmd_ext.size[0] = sz >> 16;
612 c->u.dma_cmd_ext.size[1] = sz >> 8;
613 c->u.dma_cmd_ext.size[2] = sz;
614 cmd_len = offsetof(struct wilc_spi_cmd, u.dma_cmd_ext.crc);
615 if (spi_priv->crc7_enabled)
616 c->u.dma_cmd_ext.crc[0] = wilc_get_crc7(wb, cmd_len);
617 } else {
618 dev_err(&spi->dev, "dma read write cmd [%x] not supported\n",
619 cmd);
620 return -EINVAL;
621 }
622 if (spi_priv->crc7_enabled)
623 cmd_len += 1;
624
625 resp_len = sizeof(*r);
626
627 if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
628 dev_err(&spi->dev, "spi buffer size too small (%d)(%d) (%zu)\n",
629 cmd_len, resp_len, ARRAY_SIZE(wb));
630 return -EINVAL;
631 }
632
633 if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
634 dev_err(&spi->dev, "Failed cmd write, bus error...\n");
635 return -EINVAL;
636 }
637
638 r = (struct wilc_spi_rsp_data *)&rb[cmd_len];
639 if (r->rsp_cmd_type != cmd) {
640 dev_err(&spi->dev,
641 "Failed cmd response, cmd (%02x), resp (%02x)\n",
642 cmd, r->rsp_cmd_type);
643 return -EINVAL;
644 }
645
646 if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
647 dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
648 r->status);
649 return -EINVAL;
650 }
651
652 if (cmd == CMD_DMA_WRITE || cmd == CMD_DMA_EXT_WRITE)
653 return 0;
654
655 while (sz > 0) {
656 int nbytes;
657 u8 rsp;
658
659 if (sz <= DATA_PKT_SZ)
660 nbytes = sz;
661 else
662 nbytes = DATA_PKT_SZ;
663
664
665
666
667 retry = 100;
668 do {
669 if (wilc_spi_rx(wilc, &rsp, 1)) {
670 dev_err(&spi->dev,
671 "Failed resp read, bus err\n");
672 return -EINVAL;
673 }
674 if (WILC_GET_RESP_HDR_START(rsp) == 0xf)
675 break;
676 } while (retry--);
677
678
679
680
681 if (wilc_spi_rx(wilc, &b[ix], nbytes)) {
682 dev_err(&spi->dev,
683 "Failed block read, bus err\n");
684 return -EINVAL;
685 }
686
687
688
689
690 if (spi_priv->crc16_enabled) {
691 if (wilc_spi_rx(wilc, crc, 2)) {
692 dev_err(&spi->dev,
693 "Failed block CRC read, bus err\n");
694 return -EINVAL;
695 }
696 crc_recv = (crc[0] << 8) | crc[1];
697 crc_calc = crc_itu_t(0xffff, &b[ix], nbytes);
698 if (crc_recv != crc_calc) {
699 dev_err(&spi->dev, "%s: bad CRC 0x%04x "
700 "(calculated 0x%04x)\n", __func__,
701 crc_recv, crc_calc);
702 return -EINVAL;
703 }
704 }
705
706 ix += nbytes;
707 sz -= nbytes;
708 }
709 return 0;
710}
711
712static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
713{
714 struct spi_device *spi = to_spi_device(wilc->dev);
715 int result;
716 u8 cmd = CMD_SINGLE_READ;
717 u8 clockless = 0;
718
719 if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
720
721 cmd = CMD_INTERNAL_READ;
722 clockless = 1;
723 }
724
725 result = wilc_spi_single_read(wilc, cmd, addr, data, clockless);
726 if (result) {
727 dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr);
728 return result;
729 }
730
731 le32_to_cpus(data);
732
733 return 0;
734}
735
736static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
737{
738 struct spi_device *spi = to_spi_device(wilc->dev);
739 int result;
740
741 if (size <= 4)
742 return -EINVAL;
743
744 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, buf, size);
745 if (result) {
746 dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr);
747 return result;
748 }
749
750 return 0;
751}
752
753static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat)
754{
755 struct spi_device *spi = to_spi_device(wilc->dev);
756 int result;
757
758 result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, dat, 0);
759 if (result) {
760 dev_err(&spi->dev, "Failed internal write cmd...\n");
761 return result;
762 }
763
764 return 0;
765}
766
767static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data)
768{
769 struct spi_device *spi = to_spi_device(wilc->dev);
770 struct wilc_spi *spi_priv = wilc->bus_data;
771 int result;
772
773 result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, data, 0);
774 if (result) {
775 if (!spi_priv->probing_crc)
776 dev_err(&spi->dev, "Failed internal read cmd...\n");
777 return result;
778 }
779
780 le32_to_cpus(data);
781
782 return 0;
783}
784
785
786
787
788
789
790
791static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data)
792{
793 struct spi_device *spi = to_spi_device(wilc->dev);
794 int result;
795 u8 cmd = CMD_SINGLE_WRITE;
796 u8 clockless = 0;
797
798 if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) {
799
800 cmd = CMD_INTERNAL_WRITE;
801 clockless = 1;
802 }
803
804 result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless);
805 if (result) {
806 dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr);
807 return result;
808 }
809
810 return 0;
811}
812
813static int spi_data_rsp(struct wilc *wilc, u8 cmd)
814{
815 struct spi_device *spi = to_spi_device(wilc->dev);
816 int result, i;
817 u8 rsp[4];
818
819
820
821
822
823
824
825
826
827
828
829
830
831 result = wilc_spi_rx(wilc, rsp, sizeof(rsp));
832 if (result) {
833 dev_err(&spi->dev, "Failed bus error...\n");
834 return result;
835 }
836
837 for (i = sizeof(rsp) - 2; i >= 0; --i)
838 if (FIELD_GET(RSP_START_FIELD, rsp[i]) == RSP_START_TAG)
839 break;
840
841 if (i < 0) {
842 dev_err(&spi->dev,
843 "Data packet response missing (%02x %02x %02x %02x)\n",
844 rsp[0], rsp[1], rsp[2], rsp[3]);
845 return -1;
846 }
847
848
849
850 if (FIELD_GET(RSP_TYPE_FIELD, rsp[i]) != RSP_TYPE_LAST_PACKET
851 || rsp[i + 1] != RSP_STATE_NO_ERROR) {
852 dev_err(&spi->dev, "Data response error (%02x %02x)\n",
853 rsp[i], rsp[i + 1]);
854 return -1;
855 }
856 return 0;
857}
858
859static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
860{
861 struct spi_device *spi = to_spi_device(wilc->dev);
862 int result;
863
864
865
866
867 if (size <= 4)
868 return -EINVAL;
869
870 result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size);
871 if (result) {
872 dev_err(&spi->dev,
873 "Failed cmd, write block (%08x)...\n", addr);
874 return result;
875 }
876
877
878
879
880 result = spi_data_write(wilc, buf, size);
881 if (result) {
882 dev_err(&spi->dev, "Failed block data write...\n");
883 return result;
884 }
885
886
887
888
889 return spi_data_rsp(wilc, CMD_DMA_EXT_WRITE);
890}
891
892
893
894
895
896
897
898static int wilc_spi_deinit(struct wilc *wilc)
899{
900
901
902
903 return 0;
904}
905
906static int wilc_spi_init(struct wilc *wilc, bool resume)
907{
908 struct spi_device *spi = to_spi_device(wilc->dev);
909 struct wilc_spi *spi_priv = wilc->bus_data;
910 u32 reg;
911 u32 chipid;
912 int ret, i;
913
914 if (spi_priv->isinit) {
915
916 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
917 if (ret == 0)
918 return 0;
919
920 dev_err(&spi->dev, "Fail cmd read chip id...\n");
921 }
922
923
924
925
926
927
928
929
930
931
932 spi_priv->probing_crc = true;
933 spi_priv->crc7_enabled = enable_crc7;
934 spi_priv->crc16_enabled = false;
935 for (i = 0; i < 2; ++i) {
936 ret = spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);
937 if (ret == 0)
938 break;
939 spi_priv->crc7_enabled = !enable_crc7;
940 }
941 if (ret) {
942 dev_err(&spi->dev, "Failed with CRC7 on and off.\n");
943 return ret;
944 }
945
946
947 reg &= ~(PROTOCOL_REG_CRC7_MASK | PROTOCOL_REG_CRC16_MASK);
948 if (enable_crc7)
949 reg |= PROTOCOL_REG_CRC7_MASK;
950 if (enable_crc16)
951 reg |= PROTOCOL_REG_CRC16_MASK;
952
953
954 BUILD_BUG_ON(DATA_PKT_LOG_SZ < DATA_PKT_LOG_SZ_MIN
955 || DATA_PKT_LOG_SZ > DATA_PKT_LOG_SZ_MAX);
956 reg &= ~PROTOCOL_REG_PKT_SZ_MASK;
957 reg |= FIELD_PREP(PROTOCOL_REG_PKT_SZ_MASK,
958 DATA_PKT_LOG_SZ - DATA_PKT_LOG_SZ_MIN);
959
960
961 ret = spi_internal_write(wilc, WILC_SPI_PROTOCOL_OFFSET, reg);
962 if (ret) {
963 dev_err(&spi->dev,
964 "[wilc spi %d]: Failed internal write reg\n",
965 __LINE__);
966 return ret;
967 }
968
969 spi_priv->crc7_enabled = enable_crc7;
970 spi_priv->crc16_enabled = enable_crc16;
971
972
973 spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®);
974
975 spi_priv->probing_crc = false;
976
977
978
979
980 ret = wilc_spi_read_reg(wilc, WILC_CHIPID, &chipid);
981 if (ret) {
982 dev_err(&spi->dev, "Fail cmd read chip id...\n");
983 return ret;
984 }
985
986 spi_priv->isinit = true;
987
988 return 0;
989}
990
991static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
992{
993 int ret;
994
995 ret = spi_internal_read(wilc,
996 WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE, size);
997 *size = FIELD_GET(IRQ_DMA_WD_CNT_MASK, *size);
998
999 return ret;
1000}
1001
1002static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
1003{
1004 return spi_internal_read(wilc, WILC_SPI_INT_STATUS - WILC_SPI_REG_BASE,
1005 int_status);
1006}
1007
1008static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
1009{
1010 int ret;
1011 int retry = SPI_ENABLE_VMM_RETRY_LIMIT;
1012 u32 check;
1013
1014 while (retry) {
1015 ret = spi_internal_write(wilc,
1016 WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,
1017 val);
1018 if (ret)
1019 break;
1020
1021 ret = spi_internal_read(wilc,
1022 WILC_SPI_INT_CLEAR - WILC_SPI_REG_BASE,
1023 &check);
1024 if (ret || ((check & EN_VMM) == (val & EN_VMM)))
1025 break;
1026
1027 retry--;
1028 }
1029 return ret;
1030}
1031
1032static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
1033{
1034 struct spi_device *spi = to_spi_device(wilc->dev);
1035 u32 reg;
1036 int ret, i;
1037
1038 if (nint > MAX_NUM_INT) {
1039 dev_err(&spi->dev, "Too many interrupts (%d)...\n", nint);
1040 return -EINVAL;
1041 }
1042
1043
1044
1045
1046 ret = wilc_spi_read_reg(wilc, WILC_PIN_MUX_0, ®);
1047 if (ret) {
1048 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1049 WILC_PIN_MUX_0);
1050 return ret;
1051 }
1052 reg |= BIT(8);
1053 ret = wilc_spi_write_reg(wilc, WILC_PIN_MUX_0, reg);
1054 if (ret) {
1055 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1056 WILC_PIN_MUX_0);
1057 return ret;
1058 }
1059
1060
1061
1062
1063 ret = wilc_spi_read_reg(wilc, WILC_INTR_ENABLE, ®);
1064 if (ret) {
1065 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1066 WILC_INTR_ENABLE);
1067 return ret;
1068 }
1069
1070 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
1071 reg |= (BIT((27 + i)));
1072
1073 ret = wilc_spi_write_reg(wilc, WILC_INTR_ENABLE, reg);
1074 if (ret) {
1075 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1076 WILC_INTR_ENABLE);
1077 return ret;
1078 }
1079 if (nint) {
1080 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);
1081 if (ret) {
1082 dev_err(&spi->dev, "Failed read reg (%08x)...\n",
1083 WILC_INTR2_ENABLE);
1084 return ret;
1085 }
1086
1087 for (i = 0; (i < 3) && (nint > 0); i++, nint--)
1088 reg |= BIT(i);
1089
1090 ret = wilc_spi_read_reg(wilc, WILC_INTR2_ENABLE, ®);
1091 if (ret) {
1092 dev_err(&spi->dev, "Failed write reg (%08x)...\n",
1093 WILC_INTR2_ENABLE);
1094 return ret;
1095 }
1096 }
1097
1098 return 0;
1099}
1100
1101
1102static const struct wilc_hif_func wilc_hif_spi = {
1103 .hif_init = wilc_spi_init,
1104 .hif_deinit = wilc_spi_deinit,
1105 .hif_read_reg = wilc_spi_read_reg,
1106 .hif_write_reg = wilc_spi_write_reg,
1107 .hif_block_rx = wilc_spi_read,
1108 .hif_block_tx = wilc_spi_write,
1109 .hif_read_int = wilc_spi_read_int,
1110 .hif_clear_int_ext = wilc_spi_clear_int_ext,
1111 .hif_read_size = wilc_spi_read_size,
1112 .hif_block_tx_ext = wilc_spi_write,
1113 .hif_block_rx_ext = wilc_spi_read,
1114 .hif_sync_ext = wilc_spi_sync_ext,
1115};
1116