forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathgrcan.c
1741 lines (1471 loc) · 49.3 KB
/
grcan.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
*
* 2012 (c) Aeroflex Gaisler AB
*
* This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
* VHDL IP core library.
*
* Full documentation of the GRCAN core can be found here:
* http://www.gaisler.com/products/grlib/grip.pdf
*
* See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
* open firmware properties.
*
* See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
* sysfs interface.
*
* See "Documentation/admin-guide/kernel-parameters.rst" for information on the module
* parameters.
*
* Contributors: Andreas Larsson <andreas@gaisler.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/can/dev.h>
#include <linux/spinlock.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/dma-mapping.h>
#define DRV_NAME "grcan"
#define GRCAN_NAPI_WEIGHT 32
#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
struct grcan_registers {
u32 conf; /* 0x00 */
u32 stat; /* 0x04 */
u32 ctrl; /* 0x08 */
u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
u32 smask; /* 0x18 - CanMASK */
u32 scode; /* 0x1c - CanCODE */
u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
u32 pimsr; /* 0x100 */
u32 pimr; /* 0x104 */
u32 pisr; /* 0x108 */
u32 pir; /* 0x10C */
u32 imr; /* 0x110 */
u32 picr; /* 0x114 */
u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
u32 txctrl; /* 0x200 */
u32 txaddr; /* 0x204 */
u32 txsize; /* 0x208 */
u32 txwr; /* 0x20C */
u32 txrd; /* 0x210 */
u32 txirq; /* 0x214 */
u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
u32 rxctrl; /* 0x300 */
u32 rxaddr; /* 0x304 */
u32 rxsize; /* 0x308 */
u32 rxwr; /* 0x30C */
u32 rxrd; /* 0x310 */
u32 rxirq; /* 0x314 */
u32 rxmask; /* 0x318 */
u32 rxcode; /* 0x31C */
};
#define GRCAN_CONF_ABORT 0x00000001
#define GRCAN_CONF_ENABLE0 0x00000002
#define GRCAN_CONF_ENABLE1 0x00000004
#define GRCAN_CONF_SELECT 0x00000008
#define GRCAN_CONF_SILENT 0x00000010
#define GRCAN_CONF_SAM 0x00000020 /* Available in some hardware */
#define GRCAN_CONF_BPR 0x00000300 /* Note: not BRP */
#define GRCAN_CONF_RSJ 0x00007000
#define GRCAN_CONF_PS1 0x00f00000
#define GRCAN_CONF_PS2 0x000f0000
#define GRCAN_CONF_SCALER 0xff000000
#define GRCAN_CONF_OPERATION \
(GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1 \
| GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
#define GRCAN_CONF_TIMING \
(GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1 \
| GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
#define GRCAN_CONF_RSJ_MIN 1
#define GRCAN_CONF_RSJ_MAX 4
#define GRCAN_CONF_PS1_MIN 1
#define GRCAN_CONF_PS1_MAX 15
#define GRCAN_CONF_PS2_MIN 2
#define GRCAN_CONF_PS2_MAX 8
#define GRCAN_CONF_SCALER_MIN 0
#define GRCAN_CONF_SCALER_MAX 255
#define GRCAN_CONF_SCALER_INC 1
#define GRCAN_CONF_BPR_BIT 8
#define GRCAN_CONF_RSJ_BIT 12
#define GRCAN_CONF_PS1_BIT 20
#define GRCAN_CONF_PS2_BIT 16
#define GRCAN_CONF_SCALER_BIT 24
#define GRCAN_STAT_PASS 0x000001
#define GRCAN_STAT_OFF 0x000002
#define GRCAN_STAT_OR 0x000004
#define GRCAN_STAT_AHBERR 0x000008
#define GRCAN_STAT_ACTIVE 0x000010
#define GRCAN_STAT_RXERRCNT 0x00ff00
#define GRCAN_STAT_TXERRCNT 0xff0000
#define GRCAN_STAT_ERRCTR_RELATED (GRCAN_STAT_PASS | GRCAN_STAT_OFF)
#define GRCAN_STAT_RXERRCNT_BIT 8
#define GRCAN_STAT_TXERRCNT_BIT 16
#define GRCAN_STAT_ERRCNT_WARNING_LIMIT 96
#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT 127
#define GRCAN_CTRL_RESET 0x2
#define GRCAN_CTRL_ENABLE 0x1
#define GRCAN_TXCTRL_ENABLE 0x1
#define GRCAN_TXCTRL_ONGOING 0x2
#define GRCAN_TXCTRL_SINGLE 0x4
#define GRCAN_RXCTRL_ENABLE 0x1
#define GRCAN_RXCTRL_ONGOING 0x2
/* Relative offset of IRQ sources to AMBA Plug&Play */
#define GRCAN_IRQIX_IRQ 0
#define GRCAN_IRQIX_TXSYNC 1
#define GRCAN_IRQIX_RXSYNC 2
#define GRCAN_IRQ_PASS 0x00001
#define GRCAN_IRQ_OFF 0x00002
#define GRCAN_IRQ_OR 0x00004
#define GRCAN_IRQ_RXAHBERR 0x00008
#define GRCAN_IRQ_TXAHBERR 0x00010
#define GRCAN_IRQ_RXIRQ 0x00020
#define GRCAN_IRQ_TXIRQ 0x00040
#define GRCAN_IRQ_RXFULL 0x00080
#define GRCAN_IRQ_TXEMPTY 0x00100
#define GRCAN_IRQ_RX 0x00200
#define GRCAN_IRQ_TX 0x00400
#define GRCAN_IRQ_RXSYNC 0x00800
#define GRCAN_IRQ_TXSYNC 0x01000
#define GRCAN_IRQ_RXERRCTR 0x02000
#define GRCAN_IRQ_TXERRCTR 0x04000
#define GRCAN_IRQ_RXMISS 0x08000
#define GRCAN_IRQ_TXLOSS 0x10000
#define GRCAN_IRQ_NONE 0
#define GRCAN_IRQ_ALL \
(GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR \
| GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR \
| GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ \
| GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY \
| GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC \
| GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR \
| GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS \
| GRCAN_IRQ_TXLOSS)
#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
| GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR \
| GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR \
| GRCAN_IRQ_TXLOSS)
#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
#define GRCAN_MSG_SIZE 16
#define GRCAN_MSG_IDE 0x80000000
#define GRCAN_MSG_RTR 0x40000000
#define GRCAN_MSG_BID 0x1ffc0000
#define GRCAN_MSG_EID 0x1fffffff
#define GRCAN_MSG_IDE_BIT 31
#define GRCAN_MSG_RTR_BIT 30
#define GRCAN_MSG_BID_BIT 18
#define GRCAN_MSG_EID_BIT 0
#define GRCAN_MSG_DLC 0xf0000000
#define GRCAN_MSG_TXERRC 0x00ff0000
#define GRCAN_MSG_RXERRC 0x0000ff00
#define GRCAN_MSG_DLC_BIT 28
#define GRCAN_MSG_TXERRC_BIT 16
#define GRCAN_MSG_RXERRC_BIT 8
#define GRCAN_MSG_AHBERR 0x00000008
#define GRCAN_MSG_OR 0x00000004
#define GRCAN_MSG_OFF 0x00000002
#define GRCAN_MSG_PASS 0x00000001
#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
#define GRCAN_BUFFER_ALIGNMENT 1024
#define GRCAN_DEFAULT_BUFFER_SIZE 1024
#define GRCAN_VALID_TR_SIZE_MASK 0x001fffc0
#define GRCAN_INVALID_BUFFER_SIZE(s) \
((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
#error "Invalid default buffer size"
#endif
struct grcan_dma_buffer {
size_t size;
void *buf;
dma_addr_t handle;
};
struct grcan_dma {
size_t base_size;
void *base_buf;
dma_addr_t base_handle;
struct grcan_dma_buffer tx;
struct grcan_dma_buffer rx;
};
/* GRCAN configuration parameters */
struct grcan_device_config {
unsigned short enable0;
unsigned short enable1;
unsigned short select;
unsigned int txsize;
unsigned int rxsize;
};
#define GRCAN_DEFAULT_DEVICE_CONFIG { \
.enable0 = 0, \
.enable1 = 0, \
.select = 0, \
.txsize = GRCAN_DEFAULT_BUFFER_SIZE, \
.rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \
}
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
#define GRLIB_VERSION_MASK 0xffff
/* GRCAN private data structure */
struct grcan_priv {
struct can_priv can; /* must be the first member */
struct net_device *dev;
struct napi_struct napi;
struct grcan_registers __iomem *regs; /* ioremap'ed registers */
struct grcan_device_config config;
struct grcan_dma dma;
struct sk_buff **echo_skb; /* We allocate this on our own */
u8 *txdlc; /* Length of queued frames */
/* The echo skb pointer, pointing into echo_skb and indicating which
* frames can be echoed back. See the "Notes on the tx cyclic buffer
* handling"-comment for grcan_start_xmit for more details.
*/
u32 eskbp;
/* Lock for controlling changes to the netif tx queue state, accesses to
* the echo_skb pointer eskbp and for making sure that a running reset
* and/or a close of the interface is done without interference from
* other parts of the code.
*
* The echo_skb pointer, eskbp, should only be accessed under this lock
* as it can be changed in several places and together with decisions on
* whether to wake up the tx queue.
*
* The tx queue must never be woken up if there is a running reset or
* close in progress.
*
* A running reset (see below on need_txbug_workaround) should never be
* done if the interface is closing down and several running resets
* should never be scheduled simultaneously.
*/
spinlock_t lock;
/* Whether a workaround is needed due to a bug in older hardware. In
* this case, the driver both tries to prevent the bug from being
* triggered and recovers, if the bug nevertheless happens, by doing a
* running reset. A running reset, resets the device and continues from
* where it were without being noticeable from outside the driver (apart
* from slight delays).
*/
bool need_txbug_workaround;
/* To trigger initization of running reset and to trigger running reset
* respectively in the case of a hanged device due to a txbug.
*/
struct timer_list hang_timer;
struct timer_list rr_timer;
/* To avoid waking up the netif queue and restarting timers
* when a reset is scheduled or when closing of the device is
* undergoing
*/
bool resetting;
bool closing;
};
/* Wait time for a short wait for ongoing to clear */
#define GRCAN_SHORTWAIT_USECS 10
/* Limit on the number of transmitted bits of an eff frame according to the CAN
* specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
* control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
* bits end of frame
*/
#define GRCAN_EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)
#if defined(__BIG_ENDIAN)
static inline u32 grcan_read_reg(u32 __iomem *reg)
{
return ioread32be(reg);
}
static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
{
iowrite32be(val, reg);
}
#else
static inline u32 grcan_read_reg(u32 __iomem *reg)
{
return ioread32(reg);
}
static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
{
iowrite32(val, reg);
}
#endif
static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
{
grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
}
static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
{
grcan_write_reg(reg, grcan_read_reg(reg) | mask);
}
static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
{
return grcan_read_reg(reg) & mask;
}
static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
{
u32 old = grcan_read_reg(reg);
grcan_write_reg(reg, (old & ~mask) | (value & mask));
}
/* a and b should both be in [0,size] and a == b == size should not hold */
static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
{
u32 sum = a + b;
if (sum < size)
return sum;
else
return sum - size;
}
/* a and b should both be in [0,size) */
static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
{
return grcan_ring_add(a, size - b, size);
}
/* Available slots for new transmissions */
static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
{
u32 slots = txsize / GRCAN_MSG_SIZE - 1;
u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
return slots - used;
}
/* Configuration parameters that can be set via module parameters */
static struct grcan_device_config grcan_module_config =
GRCAN_DEFAULT_DEVICE_CONFIG;
static const struct can_bittiming_const grcan_bittiming_const = {
.name = DRV_NAME,
.tseg1_min = GRCAN_CONF_PS1_MIN + 1,
.tseg1_max = GRCAN_CONF_PS1_MAX + 1,
.tseg2_min = GRCAN_CONF_PS2_MIN,
.tseg2_max = GRCAN_CONF_PS2_MAX,
.sjw_max = GRCAN_CONF_RSJ_MAX,
.brp_min = GRCAN_CONF_SCALER_MIN + 1,
.brp_max = GRCAN_CONF_SCALER_MAX + 1,
.brp_inc = GRCAN_CONF_SCALER_INC,
};
static int grcan_set_bittiming(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
struct can_bittiming *bt = &priv->can.bittiming;
u32 timing = 0;
int bpr, rsj, ps1, ps2, scaler;
/* Should never happen - function will not be called when
* device is up
*/
if (grcan_read_bits(®s->ctrl, GRCAN_CTRL_ENABLE))
return -EBUSY;
bpr = 0; /* Note bpr and brp are different concepts */
rsj = bt->sjw;
ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
ps2 = bt->phase_seg2;
scaler = (bt->brp - 1);
netdev_dbg(dev, "Request for BPR=%d, RSJ=%d, PS1=%d, PS2=%d, SCALER=%d",
bpr, rsj, ps1, ps2, scaler);
if (!(ps1 > ps2)) {
netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
ps1, ps2);
return -EINVAL;
}
if (!(ps2 >= rsj)) {
netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
ps2, rsj);
return -EINVAL;
}
timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
netdev_info(dev, "setting timing=0x%x\n", timing);
grcan_write_bits(®s->conf, timing, GRCAN_CONF_TIMING);
return 0;
}
static int grcan_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
u32 status = grcan_read_reg(®s->stat);
bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
return 0;
}
static int grcan_poll(struct napi_struct *napi, int budget);
/* Reset device, but keep configuration information */
static void grcan_reset(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
u32 config = grcan_read_reg(®s->conf);
grcan_set_bits(®s->ctrl, GRCAN_CTRL_RESET);
grcan_write_reg(®s->conf, config);
priv->eskbp = grcan_read_reg(®s->txrd);
priv->can.state = CAN_STATE_STOPPED;
/* Turn off hardware filtering - regs->rxcode set to 0 by reset */
grcan_write_reg(®s->rxmask, 0);
}
/* stop device without changing any configurations */
static void grcan_stop_hardware(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
grcan_write_reg(®s->imr, GRCAN_IRQ_NONE);
grcan_clear_bits(®s->txctrl, GRCAN_TXCTRL_ENABLE);
grcan_clear_bits(®s->rxctrl, GRCAN_RXCTRL_ENABLE);
grcan_clear_bits(®s->ctrl, GRCAN_CTRL_ENABLE);
}
/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
* is true and free them otherwise.
*
* If budget is >= 0, stop after handling at most budget skbs. Otherwise,
* continue until priv->eskbp catches up to regs->txrd.
*
* priv->lock *must* be held when calling this function
*/
static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
struct grcan_dma *dma = &priv->dma;
struct net_device_stats *stats = &dev->stats;
int i, work_done;
/* Updates to priv->eskbp and wake-ups of the queue needs to
* be atomic towards the reads of priv->eskbp and shut-downs
* of the queue in grcan_start_xmit.
*/
u32 txrd = grcan_read_reg(®s->txrd);
for (work_done = 0; work_done < budget || budget < 0; work_done++) {
if (priv->eskbp == txrd)
break;
i = priv->eskbp / GRCAN_MSG_SIZE;
if (echo) {
/* Normal echo of messages */
stats->tx_packets++;
stats->tx_bytes += priv->txdlc[i];
priv->txdlc[i] = 0;
can_get_echo_skb(dev, i);
} else {
/* For cleanup of untransmitted messages */
can_free_echo_skb(dev, i);
}
priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
dma->tx.size);
txrd = grcan_read_reg(®s->txrd);
}
return work_done;
}
static void grcan_lost_one_shot_frame(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
struct grcan_dma *dma = &priv->dma;
u32 txrd;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
catch_up_echo_skb(dev, -1, true);
if (unlikely(grcan_read_bits(®s->txctrl, GRCAN_TXCTRL_ENABLE))) {
/* Should never happen */
netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
} else {
/* By the time an GRCAN_IRQ_TXLOSS is generated in
* one-shot mode there is no problem in writing
* to TXRD even in versions of the hardware in
* which GRCAN_TXCTRL_ONGOING is not cleared properly
* in one-shot mode.
*/
/* Skip message and discard echo-skb */
txrd = grcan_read_reg(®s->txrd);
txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
grcan_write_reg(®s->txrd, txrd);
catch_up_echo_skb(dev, -1, false);
if (!priv->resetting && !priv->closing &&
!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
netif_wake_queue(dev);
grcan_set_bits(®s->txctrl, GRCAN_TXCTRL_ENABLE);
}
}
spin_unlock_irqrestore(&priv->lock, flags);
}
static void grcan_err(struct net_device *dev, u32 sources, u32 status)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
struct grcan_dma *dma = &priv->dma;
struct net_device_stats *stats = &dev->stats;
struct can_frame cf;
/* Zero potential error_frame */
memset(&cf, 0, sizeof(cf));
/* Message lost interrupt. This might be due to arbitration error, but
* is also triggered when there is no one else on the can bus or when
* there is a problem with the hardware interface or the bus itself. As
* arbitration errors can not be singled out, no error frames are
* generated reporting this event as an arbitration error.
*/
if (sources & GRCAN_IRQ_TXLOSS) {
/* Take care of failed one-shot transmit */
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
grcan_lost_one_shot_frame(dev);
/* Stop printing as soon as error passive or bus off is in
* effect to limit the amount of txloss debug printouts.
*/
if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
netdev_dbg(dev, "tx message lost\n");
stats->tx_errors++;
}
}
/* Conditions dealing with the error counters. There is no interrupt for
* error warning, but there are interrupts for increases of the error
* counters.
*/
if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
(status & GRCAN_STAT_ERRCTR_RELATED)) {
enum can_state state = priv->can.state;
enum can_state oldstate = state;
u32 txerr = (status & GRCAN_STAT_TXERRCNT)
>> GRCAN_STAT_TXERRCNT_BIT;
u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
>> GRCAN_STAT_RXERRCNT_BIT;
/* Figure out current state */
if (status & GRCAN_STAT_OFF) {
state = CAN_STATE_BUS_OFF;
} else if (status & GRCAN_STAT_PASS) {
state = CAN_STATE_ERROR_PASSIVE;
} else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
state = CAN_STATE_ERROR_WARNING;
} else {
state = CAN_STATE_ERROR_ACTIVE;
}
/* Handle and report state changes */
if (state != oldstate) {
switch (state) {
case CAN_STATE_BUS_OFF:
netdev_dbg(dev, "bus-off\n");
netif_carrier_off(dev);
priv->can.can_stats.bus_off++;
/* Prevent the hardware from recovering from bus
* off on its own if restart is disabled.
*/
if (!priv->can.restart_ms)
grcan_stop_hardware(dev);
cf.can_id |= CAN_ERR_BUSOFF;
break;
case CAN_STATE_ERROR_PASSIVE:
netdev_dbg(dev, "Error passive condition\n");
priv->can.can_stats.error_passive++;
cf.can_id |= CAN_ERR_CRTL;
if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
break;
case CAN_STATE_ERROR_WARNING:
netdev_dbg(dev, "Error warning condition\n");
priv->can.can_stats.error_warning++;
cf.can_id |= CAN_ERR_CRTL;
if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
break;
case CAN_STATE_ERROR_ACTIVE:
netdev_dbg(dev, "Error active condition\n");
cf.can_id |= CAN_ERR_CRTL;
break;
default:
/* There are no others at this point */
break;
}
cf.data[6] = txerr;
cf.data[7] = rxerr;
priv->can.state = state;
}
/* Report automatic restarts */
if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
unsigned long flags;
cf.can_id |= CAN_ERR_RESTARTED;
netdev_dbg(dev, "restarted\n");
priv->can.can_stats.restarts++;
netif_carrier_on(dev);
spin_lock_irqsave(&priv->lock, flags);
if (!priv->resetting && !priv->closing) {
u32 txwr = grcan_read_reg(®s->txwr);
if (grcan_txspace(dma->tx.size, txwr,
priv->eskbp))
netif_wake_queue(dev);
}
spin_unlock_irqrestore(&priv->lock, flags);
}
}
/* Data overrun interrupt */
if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
netdev_dbg(dev, "got data overrun interrupt\n");
stats->rx_over_errors++;
stats->rx_errors++;
cf.can_id |= CAN_ERR_CRTL;
cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
}
/* AHB bus error interrupts (not CAN bus errors) - shut down the
* device.
*/
if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
(status & GRCAN_STAT_AHBERR)) {
char *txrx = "";
unsigned long flags;
if (sources & GRCAN_IRQ_TXAHBERR) {
txrx = "on tx ";
stats->tx_errors++;
} else if (sources & GRCAN_IRQ_RXAHBERR) {
txrx = "on rx ";
stats->rx_errors++;
}
netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
txrx);
spin_lock_irqsave(&priv->lock, flags);
/* Prevent anything to be enabled again and halt device */
priv->closing = true;
netif_stop_queue(dev);
grcan_stop_hardware(dev);
priv->can.state = CAN_STATE_STOPPED;
spin_unlock_irqrestore(&priv->lock, flags);
}
/* Pass on error frame if something to report,
* i.e. id contains some information
*/
if (cf.can_id) {
struct can_frame *skb_cf;
struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
if (skb == NULL) {
netdev_dbg(dev, "could not allocate error frame\n");
return;
}
skb_cf->can_id |= cf.can_id;
memcpy(skb_cf->data, cf.data, sizeof(cf.data));
netif_rx(skb);
}
}
static irqreturn_t grcan_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
u32 sources, status;
/* Find out the source */
sources = grcan_read_reg(®s->pimsr);
if (!sources)
return IRQ_NONE;
grcan_write_reg(®s->picr, sources);
status = grcan_read_reg(®s->stat);
/* If we got TX progress, the device has not hanged,
* so disable the hang timer
*/
if (priv->need_txbug_workaround &&
(sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
del_timer(&priv->hang_timer);
}
/* Frame(s) received or transmitted */
if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
/* Disable tx/rx interrupts and schedule poll(). No need for
* locking as interference from a running reset at worst leads
* to an extra interrupt.
*/
grcan_clear_bits(®s->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
napi_schedule(&priv->napi);
}
/* (Potential) error conditions to take care of */
if (sources & GRCAN_IRQ_ERRORS)
grcan_err(dev, sources, status);
return IRQ_HANDLED;
}
/* Reset device and restart operations from where they were.
*
* This assumes that RXCTRL & RXCTRL is properly disabled and that RX
* is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
* for single shot)
*/
static void grcan_running_reset(struct timer_list *t)
{
struct grcan_priv *priv = from_timer(priv, t, rr_timer);
struct net_device *dev = priv->dev;
struct grcan_registers __iomem *regs = priv->regs;
unsigned long flags;
/* This temporarily messes with eskbp, so we need to lock
* priv->lock
*/
spin_lock_irqsave(&priv->lock, flags);
priv->resetting = false;
del_timer(&priv->hang_timer);
del_timer(&priv->rr_timer);
if (!priv->closing) {
/* Save and reset - config register preserved by grcan_reset */
u32 imr = grcan_read_reg(®s->imr);
u32 txaddr = grcan_read_reg(®s->txaddr);
u32 txsize = grcan_read_reg(®s->txsize);
u32 txwr = grcan_read_reg(®s->txwr);
u32 txrd = grcan_read_reg(®s->txrd);
u32 eskbp = priv->eskbp;
u32 rxaddr = grcan_read_reg(®s->rxaddr);
u32 rxsize = grcan_read_reg(®s->rxsize);
u32 rxwr = grcan_read_reg(®s->rxwr);
u32 rxrd = grcan_read_reg(®s->rxrd);
grcan_reset(dev);
/* Restore */
grcan_write_reg(®s->txaddr, txaddr);
grcan_write_reg(®s->txsize, txsize);
grcan_write_reg(®s->txwr, txwr);
grcan_write_reg(®s->txrd, txrd);
priv->eskbp = eskbp;
grcan_write_reg(®s->rxaddr, rxaddr);
grcan_write_reg(®s->rxsize, rxsize);
grcan_write_reg(®s->rxwr, rxwr);
grcan_write_reg(®s->rxrd, rxrd);
/* Turn on device again */
grcan_write_reg(®s->imr, imr);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
grcan_write_reg(®s->txctrl, GRCAN_TXCTRL_ENABLE
| (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
? GRCAN_TXCTRL_SINGLE : 0));
grcan_write_reg(®s->rxctrl, GRCAN_RXCTRL_ENABLE);
grcan_write_reg(®s->ctrl, GRCAN_CTRL_ENABLE);
/* Start queue if there is size and listen-onle mode is not
* enabled
*/
if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_wake_queue(dev);
}
spin_unlock_irqrestore(&priv->lock, flags);
netdev_err(dev, "Device reset and restored\n");
}
/* Waiting time in usecs corresponding to the transmission of three maximum
* sized can frames in the given bitrate (in bits/sec). Waiting for this amount
* of time makes sure that the can controller have time to finish sending or
* receiving a frame with a good margin.
*
* usecs/sec * number of frames * bits/frame / bits/sec
*/
static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
{
return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
}
/* Set timer so that it will not fire until after a period in which the can
* controller have a good margin to finish transmitting a frame unless it has
* hanged
*/
static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
{
u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
mod_timer(timer, jiffies + wait_jiffies);
}
/* Disable channels and schedule a running reset */
static void grcan_initiate_running_reset(struct timer_list *t)
{
struct grcan_priv *priv = from_timer(priv, t, hang_timer);
struct net_device *dev = priv->dev;
struct grcan_registers __iomem *regs = priv->regs;
unsigned long flags;
netdev_err(dev, "Device seems hanged - reset scheduled\n");
spin_lock_irqsave(&priv->lock, flags);
/* The main body of this function must never be executed again
* until after an execution of grcan_running_reset
*/
if (!priv->resetting && !priv->closing) {
priv->resetting = true;
netif_stop_queue(dev);
grcan_clear_bits(®s->txctrl, GRCAN_TXCTRL_ENABLE);
grcan_clear_bits(®s->rxctrl, GRCAN_RXCTRL_ENABLE);
grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
}
spin_unlock_irqrestore(&priv->lock, flags);
}
static void grcan_free_dma_buffers(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_dma *dma = &priv->dma;
dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
dma->base_handle);
memset(dma, 0, sizeof(*dma));
}
static int grcan_allocate_dma_buffers(struct net_device *dev,
size_t tsize, size_t rsize)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_dma *dma = &priv->dma;
struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
size_t shift;
/* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
* i.e. first buffer
*/
size_t maxs = max(tsize, rsize);
size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
/* Put the small buffer after that */
size_t ssize = min(tsize, rsize);
/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
dma->base_buf = dma_alloc_coherent(&dev->dev,
dma->base_size,
&dma->base_handle,
GFP_KERNEL);
if (!dma->base_buf)
return -ENOMEM;
dma->tx.size = tsize;
dma->rx.size = rsize;
large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
small->handle = large->handle + lsize;
shift = large->handle - dma->base_handle;
large->buf = dma->base_buf + shift;
small->buf = large->buf + lsize;
return 0;
}
/* priv->lock *must* be held when calling this function */
static int grcan_start(struct net_device *dev)
{
struct grcan_priv *priv = netdev_priv(dev);
struct grcan_registers __iomem *regs = priv->regs;
u32 confop, txctrl;
grcan_reset(dev);
grcan_write_reg(®s->txaddr, priv->dma.tx.handle);
grcan_write_reg(®s->txsize, priv->dma.tx.size);
/* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
grcan_write_reg(®s->rxaddr, priv->dma.rx.handle);
grcan_write_reg(®s->rxsize, priv->dma.rx.size);
/* regs->rxwr and regs->rxrd already set to 0 by reset */
/* Enable interrupts */
grcan_read_reg(®s->pir);
grcan_write_reg(®s->imr, GRCAN_IRQ_DEFAULT);
/* Enable interfaces, channels and device */
confop = GRCAN_CONF_ABORT
| (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
| (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
| (priv->config.select ? GRCAN_CONF_SELECT : 0)
| (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
GRCAN_CONF_SILENT : 0)