30
30
#define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2)
31
31
#define IFI_CANFD_STCMD_ERROR_PASSIVE BIT(3)
32
32
#define IFI_CANFD_STCMD_BUSOFF BIT(4)
33
+ #define IFI_CANFD_STCMD_ERROR_WARNING BIT(5)
33
34
#define IFI_CANFD_STCMD_BUSMONITOR BIT(16)
34
35
#define IFI_CANFD_STCMD_LOOPBACK BIT(18)
35
36
#define IFI_CANFD_STCMD_DISABLE_CANFD BIT(24)
52
53
#define IFI_CANFD_TXSTCMD_OVERFLOW BIT(13)
53
54
54
55
#define IFI_CANFD_INTERRUPT 0xc
56
+ #define IFI_CANFD_INTERRUPT_ERROR_BUSOFF BIT(0)
55
57
#define IFI_CANFD_INTERRUPT_ERROR_WARNING BIT(1)
58
+ #define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG BIT(2)
59
+ #define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC BIT(3)
56
60
#define IFI_CANFD_INTERRUPT_ERROR_COUNTER BIT(10)
57
61
#define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY BIT(16)
58
62
#define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE BIT(22)
61
65
#define IFI_CANFD_INTERRUPT_SET_IRQ ((u32)BIT(31))
62
66
63
67
#define IFI_CANFD_IRQMASK 0x10
68
+ #define IFI_CANFD_IRQMASK_ERROR_BUSOFF BIT(0)
69
+ #define IFI_CANFD_IRQMASK_ERROR_WARNING BIT(1)
70
+ #define IFI_CANFD_IRQMASK_ERROR_STATE_CHG BIT(2)
71
+ #define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC BIT(3)
64
72
#define IFI_CANFD_IRQMASK_SET_ERR BIT(7)
65
73
#define IFI_CANFD_IRQMASK_SET_TS BIT(15)
66
74
#define IFI_CANFD_IRQMASK_TXFIFO_EMPTY BIT(16)
136
144
#define IFI_CANFD_SYSCLOCK 0x50
137
145
138
146
#define IFI_CANFD_VER 0x54
147
+ #define IFI_CANFD_VER_REV_MASK 0xff
148
+ #define IFI_CANFD_VER_REV_MIN_SUPPORTED 0x15
139
149
140
150
#define IFI_CANFD_IP_ID 0x58
141
151
#define IFI_CANFD_IP_ID_VALUE 0xD073CAFD
@@ -220,7 +230,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
220
230
221
231
if (enable ) {
222
232
enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
223
- IFI_CANFD_IRQMASK_RXFIFO_NEMPTY ;
233
+ IFI_CANFD_IRQMASK_RXFIFO_NEMPTY |
234
+ IFI_CANFD_IRQMASK_ERROR_STATE_CHG |
235
+ IFI_CANFD_IRQMASK_ERROR_WARNING |
236
+ IFI_CANFD_IRQMASK_ERROR_BUSOFF ;
224
237
if (priv -> can .ctrlmode & CAN_CTRLMODE_BERR_REPORTING )
225
238
enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER ;
226
239
}
@@ -361,12 +374,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
361
374
return 1 ;
362
375
}
363
376
364
- static int ifi_canfd_handle_lec_err (struct net_device * ndev , const u32 errctr )
377
+ static int ifi_canfd_handle_lec_err (struct net_device * ndev )
365
378
{
366
379
struct ifi_canfd_priv * priv = netdev_priv (ndev );
367
380
struct net_device_stats * stats = & ndev -> stats ;
368
381
struct can_frame * cf ;
369
382
struct sk_buff * skb ;
383
+ u32 errctr = readl (priv -> base + IFI_CANFD_ERROR_CTR );
370
384
const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
371
385
IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
372
386
IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
@@ -449,6 +463,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
449
463
450
464
switch (new_state ) {
451
465
case CAN_STATE_ERROR_ACTIVE :
466
+ /* error active state */
467
+ priv -> can .can_stats .error_warning ++ ;
468
+ priv -> can .state = CAN_STATE_ERROR_ACTIVE ;
469
+ break ;
470
+ case CAN_STATE_ERROR_WARNING :
452
471
/* error warning state */
453
472
priv -> can .can_stats .error_warning ++ ;
454
473
priv -> can .state = CAN_STATE_ERROR_WARNING ;
@@ -477,7 +496,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
477
496
ifi_canfd_get_berr_counter (ndev , & bec );
478
497
479
498
switch (new_state ) {
480
- case CAN_STATE_ERROR_ACTIVE :
499
+ case CAN_STATE_ERROR_WARNING :
481
500
/* error warning state */
482
501
cf -> can_id |= CAN_ERR_CRTL ;
483
502
cf -> data [1 ] = (bec .txerr > bec .rxerr ) ?
@@ -510,22 +529,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
510
529
return 1 ;
511
530
}
512
531
513
- static int ifi_canfd_handle_state_errors (struct net_device * ndev , u32 stcmd )
532
+ static int ifi_canfd_handle_state_errors (struct net_device * ndev )
514
533
{
515
534
struct ifi_canfd_priv * priv = netdev_priv (ndev );
535
+ u32 stcmd = readl (priv -> base + IFI_CANFD_STCMD );
516
536
int work_done = 0 ;
517
- u32 isr ;
518
537
519
- /*
520
- * The ErrWarn condition is a little special, since the bit is
521
- * located in the INTERRUPT register instead of STCMD register.
522
- */
523
- isr = readl (priv -> base + IFI_CANFD_INTERRUPT );
524
- if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING ) &&
538
+ if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE ) &&
539
+ (priv -> can .state != CAN_STATE_ERROR_ACTIVE )) {
540
+ netdev_dbg (ndev , "Error, entered active state\n" );
541
+ work_done += ifi_canfd_handle_state_change (ndev ,
542
+ CAN_STATE_ERROR_ACTIVE );
543
+ }
544
+
545
+ if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING ) &&
525
546
(priv -> can .state != CAN_STATE_ERROR_WARNING )) {
526
- /* Clear the interrupt */
527
- writel (IFI_CANFD_INTERRUPT_ERROR_WARNING ,
528
- priv -> base + IFI_CANFD_INTERRUPT );
529
547
netdev_dbg (ndev , "Error, entered warning state\n" );
530
548
work_done += ifi_canfd_handle_state_change (ndev ,
531
549
CAN_STATE_ERROR_WARNING );
@@ -552,26 +570,19 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
552
570
{
553
571
struct net_device * ndev = napi -> dev ;
554
572
struct ifi_canfd_priv * priv = netdev_priv (ndev );
555
- const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE |
556
- IFI_CANFD_STCMD_BUSOFF ;
557
- int work_done = 0 ;
558
-
559
- u32 stcmd = readl (priv -> base + IFI_CANFD_STCMD );
560
573
u32 rxstcmd = readl (priv -> base + IFI_CANFD_RXSTCMD );
561
- u32 errctr = readl ( priv -> base + IFI_CANFD_ERROR_CTR ) ;
574
+ int work_done = 0 ;
562
575
563
576
/* Handle bus state changes */
564
- if ((stcmd & stcmd_state_mask ) ||
565
- ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE ) == 0 ))
566
- work_done += ifi_canfd_handle_state_errors (ndev , stcmd );
577
+ work_done += ifi_canfd_handle_state_errors (ndev );
567
578
568
579
/* Handle lost messages on RX */
569
580
if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW )
570
581
work_done += ifi_canfd_handle_lost_msg (ndev );
571
582
572
583
/* Handle lec errors on the bus */
573
584
if (priv -> can .ctrlmode & CAN_CTRLMODE_BERR_REPORTING )
574
- work_done += ifi_canfd_handle_lec_err (ndev , errctr );
585
+ work_done += ifi_canfd_handle_lec_err (ndev );
575
586
576
587
/* Handle normal messages on RX */
577
588
if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY ))
@@ -592,12 +603,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
592
603
struct net_device_stats * stats = & ndev -> stats ;
593
604
const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
594
605
IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
606
+ IFI_CANFD_INTERRUPT_ERROR_COUNTER |
607
+ IFI_CANFD_INTERRUPT_ERROR_STATE_CHG |
595
608
IFI_CANFD_INTERRUPT_ERROR_WARNING |
596
- IFI_CANFD_INTERRUPT_ERROR_COUNTER ;
609
+ IFI_CANFD_INTERRUPT_ERROR_BUSOFF ;
597
610
const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
598
611
IFI_CANFD_INTERRUPT_TXFIFO_REMOVE ;
599
- const u32 clr_irq_mask = ~((u32 )(IFI_CANFD_INTERRUPT_SET_IRQ |
600
- IFI_CANFD_INTERRUPT_ERROR_WARNING ));
612
+ const u32 clr_irq_mask = ~((u32 )IFI_CANFD_INTERRUPT_SET_IRQ );
601
613
u32 isr ;
602
614
603
615
isr = readl (priv -> base + IFI_CANFD_INTERRUPT );
@@ -933,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
933
945
struct resource * res ;
934
946
void __iomem * addr ;
935
947
int irq , ret ;
936
- u32 id ;
948
+ u32 id , rev ;
937
949
938
950
res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
939
951
addr = devm_ioremap_resource (dev , res );
@@ -947,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
947
959
return - EINVAL ;
948
960
}
949
961
962
+ rev = readl (addr + IFI_CANFD_VER ) & IFI_CANFD_VER_REV_MASK ;
963
+ if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED ) {
964
+ dev_err (dev , "This block is too old (rev %i), minimum supported is rev %i\n" ,
965
+ rev , IFI_CANFD_VER_REV_MIN_SUPPORTED );
966
+ return - EINVAL ;
967
+ }
968
+
950
969
ndev = alloc_candev (sizeof (* priv ), 1 );
951
970
if (!ndev )
952
971
return - ENOMEM ;
0 commit comments