aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2014-06-25 08:05:19 -0400
committerDong Aisheng <b29396@freescale.com>2014-06-29 23:36:16 -0400
commit19d35d8c55fb1edba73c70cf133c8a361e56a956 (patch)
tree750fea795b6a200345583ad076ab4b9781e65cbe /drivers/net
parentd965cfdbf03d972baac616e9f1d6c9e50d0d3c5c (diff)
ENGR00320354-1 can: m_can: add bus error handling
Add bus error, state change, lost message handling mechanism. Signed-off-by: Dong Aisheng <b29396@freescale.com> (cherry picked from commit f2f95e529927f3debeef1fa19ac560d2ebf71140)
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/can/m_can.c271
1 files changed, 240 insertions, 31 deletions
diff --git a/drivers/net/can/m_can.c b/drivers/net/can/m_can.c
index 4397cfe2ec31..1a320aff2b27 100644
--- a/drivers/net/can/m_can.c
+++ b/drivers/net/can/m_can.c
@@ -83,6 +83,18 @@ enum m_can_reg {
83 M_CAN_TXEFA = 0xf8, 83 M_CAN_TXEFA = 0xf8,
84}; 84};
85 85
86/* m_can lec values */
87enum m_can_lec_type {
88 LEC_NO_ERROR = 0,
89 LEC_STUFF_ERROR,
90 LEC_FORM_ERROR,
91 LEC_ACK_ERROR,
92 LEC_BIT1_ERROR,
93 LEC_BIT0_ERROR,
94 LEC_CRC_ERROR,
95 LEC_UNUSED,
96};
97
86/* CC Control Register(CCCR) */ 98/* CC Control Register(CCCR) */
87#define CCCR_CCE BIT(1) 99#define CCCR_CCE BIT(1)
88#define CCCR_INIT BIT(0) 100#define CCCR_INIT BIT(0)
@@ -97,6 +109,19 @@ enum m_can_reg {
97#define BTR_SJW_SHIFT 0 109#define BTR_SJW_SHIFT 0
98#define BTR_SJW_MASK 0xf 110#define BTR_SJW_MASK 0xf
99 111
112/* Error Counter Register(ECR) */
113#define ECR_RP BIT(15)
114#define ECR_REC_SHIFT 8
115#define ECR_REC_MASK (0x7f << ECR_REC_SHIFT)
116#define ECR_TEC_SHIFT 0
117#define ECR_TEC_MASK 0xff
118
119/* Protocol Status Register(PSR) */
120#define PSR_BO BIT(7)
121#define PSR_EW BIT(6)
122#define PSR_EP BIT(5)
123#define PSR_LEC_MASK 0x7
124
100/* Interrupt Register(IR) */ 125/* Interrupt Register(IR) */
101#define IR_ALL_INT 0xffffffff 126#define IR_ALL_INT 0xffffffff
102#define IR_STE BIT(31) 127#define IR_STE BIT(31)
@@ -131,10 +156,11 @@ enum m_can_reg {
131#define IR_RF0F BIT(2) 156#define IR_RF0F BIT(2)
132#define IR_RF0W BIT(1) 157#define IR_RF0W BIT(1)
133#define IR_RF0N BIT(0) 158#define IR_RF0N BIT(0)
134#define IR_ERR_ALL (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE | \ 159#define IR_ERR_STATE (IR_BO | IR_EW | IR_EP)
135 IR_WDI | IR_BO | IR_EW | IR_EP | IR_ELO | IR_BEU | \ 160#define IR_ERR_BUS (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE | \
136 IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ 161 IR_WDI | IR_ELO | IR_BEU | IR_BEC | IR_TOO | IR_MRAF | \
137 IR_RF0L) 162 IR_TSW | IR_TEFL | IR_RF1L | IR_RF0L)
163#define IR_ERR_ALL (IR_ERR_STATE | IR_ERR_BUS)
138 164
139/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ 165/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
140#define RXFC_FWM_OFF 24 166#define RXFC_FWM_OFF 24
@@ -320,12 +346,175 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
320 return num_rx_pkts; 346 return num_rx_pkts;
321} 347}
322 348
349static int m_can_handle_lost_msg(struct net_device *dev)
350{
351 struct net_device_stats *stats = &dev->stats;
352 struct sk_buff *skb;
353 struct can_frame *frame;
354
355 netdev_err(dev, "msg lost in rxf0\n");
356
357 skb = alloc_can_err_skb(dev, &frame);
358 if (unlikely(!skb))
359 return 0;
360
361 frame->can_id |= CAN_ERR_CRTL;
362 frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
363 stats->rx_errors++;
364 stats->rx_over_errors++;
365
366 netif_receive_skb(skb);
367
368 return 1;
369}
370
371static int m_can_handle_bus_err(struct net_device *dev,
372 enum m_can_lec_type lec_type)
373{
374 struct m_can_priv *priv = netdev_priv(dev);
375 struct net_device_stats *stats = &dev->stats;
376 struct can_frame *cf;
377 struct sk_buff *skb;
378
379 /* early exit if no lec update */
380 if (lec_type == LEC_UNUSED)
381 return 0;
382
383 /* propagate the error condition to the CAN stack */
384 skb = alloc_can_err_skb(dev, &cf);
385 if (unlikely(!skb))
386 return 0;
387
388 /*
389 * check for 'last error code' which tells us the
390 * type of the last error to occur on the CAN bus
391 */
392 priv->can.can_stats.bus_error++;
393 stats->rx_errors++;
394 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
395 cf->data[2] |= CAN_ERR_PROT_UNSPEC;
396
397 switch (lec_type) {
398 case LEC_STUFF_ERROR:
399 netdev_dbg(dev, "stuff error\n");
400 cf->data[2] |= CAN_ERR_PROT_STUFF;
401 break;
402 case LEC_FORM_ERROR:
403 netdev_dbg(dev, "form error\n");
404 cf->data[2] |= CAN_ERR_PROT_FORM;
405 break;
406 case LEC_ACK_ERROR:
407 netdev_dbg(dev, "ack error\n");
408 cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
409 CAN_ERR_PROT_LOC_ACK_DEL);
410 break;
411 case LEC_BIT1_ERROR:
412 netdev_dbg(dev, "bit1 error\n");
413 cf->data[2] |= CAN_ERR_PROT_BIT1;
414 break;
415 case LEC_BIT0_ERROR:
416 netdev_dbg(dev, "bit0 error\n");
417 cf->data[2] |= CAN_ERR_PROT_BIT0;
418 break;
419 case LEC_CRC_ERROR:
420 netdev_dbg(dev, "CRC error\n");
421 cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
422 CAN_ERR_PROT_LOC_CRC_DEL);
423 break;
424 default:
425 break;
426 }
427
428 netif_receive_skb(skb);
429 stats->rx_packets++;
430 stats->rx_bytes += cf->can_dlc;
431
432 return 1;
433}
434
435static int m_can_get_berr_counter(const struct net_device *dev,
436 struct can_berr_counter *bec)
437{
438 struct m_can_priv *priv = netdev_priv(dev);
439 unsigned int ecr;
440
441 ecr = m_can_read(priv, M_CAN_ECR);
442 bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
443 bec->txerr = ecr & ECR_TEC_MASK;
444
445 return 0;
446}
447
448static int m_can_handle_state_change(struct net_device *dev,
449 enum can_state new_state)
450{
451 struct m_can_priv *priv = netdev_priv(dev);
452 struct net_device_stats *stats = &dev->stats;
453 struct can_frame *cf;
454 struct sk_buff *skb;
455 struct can_berr_counter bec;
456 unsigned int ecr;
457
458 /* propagate the error condition to the CAN stack */
459 skb = alloc_can_err_skb(dev, &cf);
460 if (unlikely(!skb))
461 return 0;
462
463 m_can_get_berr_counter(dev, &bec);
464
465 switch (new_state) {
466 case CAN_STATE_ERROR_ACTIVE:
467 /* error warning state */
468 priv->can.can_stats.error_warning++;
469 priv->can.state = CAN_STATE_ERROR_WARNING;
470 cf->can_id |= CAN_ERR_CRTL;
471 cf->data[1] = (bec.txerr > bec.rxerr) ?
472 CAN_ERR_CRTL_TX_WARNING :
473 CAN_ERR_CRTL_RX_WARNING;
474 cf->data[6] = bec.txerr;
475 cf->data[7] = bec.rxerr;
476 break;
477 case CAN_STATE_ERROR_PASSIVE:
478 /* error passive state */
479 priv->can.can_stats.error_passive++;
480 priv->can.state = CAN_STATE_ERROR_PASSIVE;
481 cf->can_id |= CAN_ERR_CRTL;
482 ecr = m_can_read(priv, M_CAN_ECR);
483 if (ecr & ECR_RP)
484 cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
485 if (bec.txerr > 127)
486 cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
487 cf->data[6] = bec.txerr;
488 cf->data[7] = bec.rxerr;
489 break;
490 case CAN_STATE_BUS_OFF:
491 /* bus-off state */
492 priv->can.state = CAN_STATE_BUS_OFF;
493 cf->can_id |= CAN_ERR_BUSOFF;
494 /*
495 * disable all interrupts in bus-off mode to ensure that
496 * the CPU is not hogged down
497 */
498 m_can_enable_all_interrupts(priv, false);
499 can_bus_off(dev);
500 break;
501 default:
502 break;
503 }
504
505 netif_receive_skb(skb);
506 stats->rx_packets++;
507 stats->rx_bytes += cf->can_dlc;
508
509 return 1;
510}
511
323static int m_can_poll(struct napi_struct *napi, int quota) 512static int m_can_poll(struct napi_struct *napi, int quota)
324{ 513{
325 struct net_device *dev = napi->dev; 514 struct net_device *dev = napi->dev;
326 struct m_can_priv *priv = netdev_priv(dev); 515 struct m_can_priv *priv = netdev_priv(dev);
327 u32 work_done = 0; 516 u32 work_done = 0;
328 u32 irqstatus; 517 u32 irqstatus, psr;
329 518
330 irqstatus = m_can_read(priv, M_CAN_IR); 519 irqstatus = m_can_read(priv, M_CAN_IR);
331 if (irqstatus) 520 if (irqstatus)
@@ -337,6 +526,48 @@ static int m_can_poll(struct napi_struct *napi, int quota)
337 if (!irqstatus) 526 if (!irqstatus)
338 goto end; 527 goto end;
339 528
529 psr = m_can_read(priv, M_CAN_PSR);
530 if (irqstatus & IR_ERR_STATE) {
531 if ((psr & PSR_EW) &&
532 (priv->can.state != CAN_STATE_ERROR_WARNING)) {
533 netdev_dbg(dev, "entered error warning state\n");
534 work_done += m_can_handle_state_change(dev,
535 CAN_STATE_ERROR_WARNING);
536 }
537
538 if ((psr & PSR_EP) &&
539 (priv->can.state != CAN_STATE_ERROR_PASSIVE)) {
540 netdev_dbg(dev, "entered error warning state\n");
541 work_done += m_can_handle_state_change(dev,
542 CAN_STATE_ERROR_PASSIVE);
543 }
544
545 if ((psr & PSR_BO) &&
546 (priv->can.state != CAN_STATE_BUS_OFF)) {
547 netdev_dbg(dev, "entered error warning state\n");
548 work_done += m_can_handle_state_change(dev,
549 CAN_STATE_BUS_OFF);
550 }
551 }
552
553 if (irqstatus & IR_ERR_BUS) {
554 if (irqstatus & IR_RF0L)
555 work_done += m_can_handle_lost_msg(dev);
556
557 /* handle lec errors on the bus */
558 if (psr & LEC_UNUSED)
559 work_done += m_can_handle_bus_err(dev,
560 psr & LEC_UNUSED);
561
562 /* other unproccessed error interrupts */
563 if (irqstatus & IR_WDI)
564 netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
565 if (irqstatus & IR_TOO)
566 netdev_err(dev, "Timeout reached\n");
567 if (irqstatus & IR_MRAF)
568 netdev_err(dev, "Message RAM access failure occurred\n");
569 }
570
340 if (irqstatus & IR_RF0N) 571 if (irqstatus & IR_RF0N)
341 /* handle events corresponding to receive message objects */ 572 /* handle events corresponding to receive message objects */
342 work_done += m_can_do_rx_poll(dev, (quota - work_done)); 573 work_done += m_can_do_rx_poll(dev, (quota - work_done));
@@ -369,31 +600,18 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
369 if (ir & IR_ALL_INT) 600 if (ir & IR_ALL_INT)
370 m_can_write(priv, M_CAN_IR, ir); 601 m_can_write(priv, M_CAN_IR, ir);
371 602
372 if (ir & IR_ERR_ALL) {
373 netdev_dbg(dev, "bus error\n");
374 /* TODO: handle bus error */
375 }
376
377 /* save irqstatus for later using */
378 priv->irqstatus = ir;
379
380 /* 603 /*
381 * schedule NAPI in case of 604 * schedule NAPI in case of
382 * - rx IRQ 605 * - rx IRQ
383 * - state change IRQ(TODO) 606 * - state change IRQ
384 * - bus error IRQ and bus error reporting (TODO) 607 * - bus error IRQ and bus error reporting
385 */ 608 */
386 if (ir & IR_RF0N) { 609 if ((ir & IR_RF0N) || (ir & IR_ERR_ALL)) {
610 priv->irqstatus = ir;
387 m_can_enable_all_interrupts(priv, false); 611 m_can_enable_all_interrupts(priv, false);
388 napi_schedule(&priv->napi); 612 napi_schedule(&priv->napi);
389 } 613 }
390 614
391 /* FIFO overflow */
392 if (ir & IR_RF0L) {
393 dev->stats.rx_over_errors++;
394 dev->stats.rx_errors++;
395 }
396
397 /* transmission complete interrupt */ 615 /* transmission complete interrupt */
398 if (ir & IR_TC) { 616 if (ir & IR_TC) {
399 netdev_dbg(dev, "tx complete\n"); 617 netdev_dbg(dev, "tx complete\n");
@@ -446,7 +664,6 @@ static int m_can_set_bittiming(struct net_device *dev)
446 * - setup bittiming 664 * - setup bittiming
447 * - TODO: 665 * - TODO:
448 * 1) other working modes support like monitor, loopback... 666 * 1) other working modes support like monitor, loopback...
449 * 2) lec error status report enable
450 */ 667 */
451static void m_can_chip_config(struct net_device *dev) 668static void m_can_chip_config(struct net_device *dev)
452{ 669{
@@ -515,14 +732,6 @@ static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
515 return 0; 732 return 0;
516} 733}
517 734
518static int m_can_get_berr_counter(const struct net_device *dev,
519 struct can_berr_counter *bec)
520{
521 /* TODO */
522
523 return 0;
524}
525
526static void free_m_can_dev(struct net_device *dev) 735static void free_m_can_dev(struct net_device *dev)
527{ 736{
528 free_candev(dev); 737 free_candev(dev);