Lines Matching +full:canfd +full:- +full:2

2  * CAN bus driver for IFI CANFD controller
7 * http://www.ifi-pld.de/IP/CANFD/canfd.html
10 * License version 2. This program is licensed "as is" without any
30 #define IFI_CANFD_STCMD_ERROR_ACTIVE BIT(2)
58 #define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG BIT(2)
70 #define IFI_CANFD_IRQMASK_ERROR_STATE_CHG BIT(2)
123 #define IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST BIT(2)
218 /* IFI CANFD private data structure */
237 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) in ifi_canfd_irq_enable()
245 priv->base + IFI_CANFD_IRQMASK); in ifi_canfd_irq_enable()
250 struct net_device_stats *stats = &ndev->stats; in ifi_canfd_read_fifo()
260 rxdlc = readl(priv->base + IFI_CANFD_RXFIFO_DLC); in ifi_canfd_read_fifo()
267 stats->rx_dropped++; in ifi_canfd_read_fifo()
274 cf->len = can_fd_dlc2len(dlc); in ifi_canfd_read_fifo()
276 cf->len = can_cc_dlc2len(dlc); in ifi_canfd_read_fifo()
278 rxid = readl(priv->base + IFI_CANFD_RXFIFO_ID); in ifi_canfd_read_fifo()
294 cf->can_id = id; in ifi_canfd_read_fifo()
297 cf->flags |= CANFD_ESI; in ifi_canfd_read_fifo()
303 cf->can_id |= CAN_RTR_FLAG; in ifi_canfd_read_fifo()
306 cf->flags |= CANFD_BRS; in ifi_canfd_read_fifo()
308 for (i = 0; i < cf->len; i += 4) { in ifi_canfd_read_fifo()
309 *(u32 *)(cf->data + i) = in ifi_canfd_read_fifo()
310 readl(priv->base + IFI_CANFD_RXFIFO_DATA + i); in ifi_canfd_read_fifo()
313 stats->rx_bytes += cf->len; in ifi_canfd_read_fifo()
315 stats->rx_packets++; in ifi_canfd_read_fifo()
318 writel(IFI_CANFD_RXSTCMD_REMOVE_MSG, priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_read_fifo()
319 writel(rx_irq_mask, priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_read_fifo()
330 rxst = readl(priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_do_rx_poll()
343 quota--; in ifi_canfd_do_rx_poll()
345 rxst = readl(priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_do_rx_poll()
353 struct net_device_stats *stats = &ndev->stats; in ifi_canfd_handle_lost_msg()
359 stats->rx_errors++; in ifi_canfd_handle_lost_msg()
360 stats->rx_over_errors++; in ifi_canfd_handle_lost_msg()
366 frame->can_id |= CAN_ERR_CRTL; in ifi_canfd_handle_lost_msg()
367 frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; in ifi_canfd_handle_lost_msg()
377 struct net_device_stats *stats = &ndev->stats; in ifi_canfd_handle_lec_err()
380 u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_handle_lec_err()
392 priv->can.can_stats.bus_error++; in ifi_canfd_handle_lec_err()
393 stats->rx_errors++; in ifi_canfd_handle_lec_err()
401 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; in ifi_canfd_handle_lec_err()
404 cf->data[2] |= CAN_ERR_PROT_OVERLOAD; in ifi_canfd_handle_lec_err()
407 cf->data[3] = CAN_ERR_PROT_LOC_ACK; in ifi_canfd_handle_lec_err()
410 cf->data[2] |= CAN_ERR_PROT_BIT0; in ifi_canfd_handle_lec_err()
413 cf->data[2] |= CAN_ERR_PROT_BIT1; in ifi_canfd_handle_lec_err()
416 cf->data[2] |= CAN_ERR_PROT_STUFF; in ifi_canfd_handle_lec_err()
419 cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; in ifi_canfd_handle_lec_err()
422 cf->data[2] |= CAN_ERR_PROT_FORM; in ifi_canfd_handle_lec_err()
424 /* Reset the error counter, ack the IRQ and re-enable the counter. */ in ifi_canfd_handle_lec_err()
425 writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_handle_lec_err()
427 priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_handle_lec_err()
428 writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_handle_lec_err()
441 err = readl(priv->base + IFI_CANFD_ERROR); in ifi_canfd_get_berr_counter()
442 bec->rxerr = (err >> IFI_CANFD_ERROR_RX_OFFSET) & in ifi_canfd_get_berr_counter()
444 bec->txerr = (err >> IFI_CANFD_ERROR_TX_OFFSET) & in ifi_canfd_get_berr_counter()
461 priv->can.can_stats.error_warning++; in ifi_canfd_handle_state_change()
462 priv->can.state = CAN_STATE_ERROR_ACTIVE; in ifi_canfd_handle_state_change()
466 priv->can.can_stats.error_warning++; in ifi_canfd_handle_state_change()
467 priv->can.state = CAN_STATE_ERROR_WARNING; in ifi_canfd_handle_state_change()
471 priv->can.can_stats.error_passive++; in ifi_canfd_handle_state_change()
472 priv->can.state = CAN_STATE_ERROR_PASSIVE; in ifi_canfd_handle_state_change()
475 /* bus-off state */ in ifi_canfd_handle_state_change()
476 priv->can.state = CAN_STATE_BUS_OFF; in ifi_canfd_handle_state_change()
478 priv->can.can_stats.bus_off++; in ifi_canfd_handle_state_change()
495 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ifi_canfd_handle_state_change()
496 cf->data[1] = (bec.txerr > bec.rxerr) ? in ifi_canfd_handle_state_change()
499 cf->data[6] = bec.txerr; in ifi_canfd_handle_state_change()
500 cf->data[7] = bec.rxerr; in ifi_canfd_handle_state_change()
504 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ifi_canfd_handle_state_change()
505 cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; in ifi_canfd_handle_state_change()
507 cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; in ifi_canfd_handle_state_change()
508 cf->data[6] = bec.txerr; in ifi_canfd_handle_state_change()
509 cf->data[7] = bec.rxerr; in ifi_canfd_handle_state_change()
512 /* bus-off state */ in ifi_canfd_handle_state_change()
513 cf->can_id |= CAN_ERR_BUSOFF; in ifi_canfd_handle_state_change()
527 u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); in ifi_canfd_handle_state_errors()
531 (priv->can.state != CAN_STATE_ERROR_ACTIVE)) { in ifi_canfd_handle_state_errors()
538 (priv->can.state != CAN_STATE_ERROR_WARNING)) { in ifi_canfd_handle_state_errors()
545 (priv->can.state != CAN_STATE_ERROR_PASSIVE)) { in ifi_canfd_handle_state_errors()
552 (priv->can.state != CAN_STATE_BUS_OFF)) { in ifi_canfd_handle_state_errors()
553 netdev_dbg(ndev, "Error, entered bus-off state\n"); in ifi_canfd_handle_state_errors()
563 struct net_device *ndev = napi->dev; in ifi_canfd_poll()
565 u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_poll()
576 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) in ifi_canfd_poll()
581 work_done += ifi_canfd_do_rx_poll(ndev, quota - work_done); in ifi_canfd_poll()
595 struct net_device_stats *stats = &ndev->stats; in ifi_canfd_isr()
607 isr = readl(priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_isr()
614 writel(clr_irq_mask, priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_isr()
619 napi_schedule(&priv->napi); in ifi_canfd_isr()
624 stats->tx_bytes += can_get_echo_skb(ndev, 0, NULL); in ifi_canfd_isr()
625 stats->tx_packets++; in ifi_canfd_isr()
638 .tseg2_min = 2, /* Time segment 2 = phase_seg2 */
641 .brp_min = 2,
649 const struct can_bittiming *bt = &priv->can.bittiming; in ifi_canfd_set_bittiming()
650 const struct can_bittiming *dbt = &priv->can.data_bittiming; in ifi_canfd_set_bittiming()
654 brp = bt->brp - 2; in ifi_canfd_set_bittiming()
655 sjw = bt->sjw - 1; in ifi_canfd_set_bittiming()
656 tseg1 = bt->prop_seg + bt->phase_seg1 - 1; in ifi_canfd_set_bittiming()
657 tseg2 = bt->phase_seg2 - 2; in ifi_canfd_set_bittiming()
662 priv->base + IFI_CANFD_TIME); in ifi_canfd_set_bittiming()
665 brp = dbt->brp - 2; in ifi_canfd_set_bittiming()
666 sjw = dbt->sjw - 1; in ifi_canfd_set_bittiming()
667 tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; in ifi_canfd_set_bittiming()
668 tseg2 = dbt->phase_seg2 - 2; in ifi_canfd_set_bittiming()
673 priv->base + IFI_CANFD_FTIME); in ifi_canfd_set_bittiming()
676 tdc = dbt->brp * (dbt->prop_seg + dbt->phase_seg1); in ifi_canfd_set_bittiming()
678 writel(IFI_CANFD_TDELAY_EN | tdc, priv->base + IFI_CANFD_TDELAY); in ifi_canfd_set_bittiming()
686 writel(mask, priv->base + IFI_CANFD_FILTER_MASK(id)); in ifi_canfd_set_filter()
687 writel(ident, priv->base + IFI_CANFD_FILTER_IDENT(id)); in ifi_canfd_set_filter()
705 /* Receive all CANFD frames */ in ifi_canfd_set_filters()
706 ifi_canfd_set_filter(ndev, 2, in ifi_canfd_set_filters()
721 writel(IFI_CANFD_STCMD_HARDRESET, priv->base + IFI_CANFD_STCMD); in ifi_canfd_start()
723 priv->base + IFI_CANFD_STCMD); in ifi_canfd_start()
729 writel(IFI_CANFD_RXSTCMD_RESET, priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_start()
730 writel(0, priv->base + IFI_CANFD_RXSTCMD); in ifi_canfd_start()
731 writel(IFI_CANFD_TXSTCMD_RESET, priv->base + IFI_CANFD_TXSTCMD); in ifi_canfd_start()
732 writel(0, priv->base + IFI_CANFD_TXSTCMD); in ifi_canfd_start()
735 writel(0, priv->base + IFI_CANFD_REPEAT); in ifi_canfd_start()
736 writel(0, priv->base + IFI_CANFD_SUSPEND); in ifi_canfd_start()
740 priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_start()
745 if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) in ifi_canfd_start()
748 if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) in ifi_canfd_start()
751 if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && in ifi_canfd_start()
752 !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) in ifi_canfd_start()
755 if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD)) in ifi_canfd_start()
758 priv->can.state = CAN_STATE_ERROR_ACTIVE; in ifi_canfd_start()
764 priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_start()
765 writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_start()
766 writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_start()
769 writel(stcmd, priv->base + IFI_CANFD_STCMD); in ifi_canfd_start()
777 writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_stop()
778 writel(0, priv->base + IFI_CANFD_ERROR_CTR); in ifi_canfd_stop()
781 writel(IFI_CANFD_STCMD_HARDRESET, priv->base + IFI_CANFD_STCMD); in ifi_canfd_stop()
784 writel(~0, priv->base + IFI_CANFD_IRQMASK); in ifi_canfd_stop()
788 priv->base + IFI_CANFD_INTERRUPT); in ifi_canfd_stop()
791 priv->can.state = CAN_STATE_STOPPED; in ifi_canfd_stop()
802 return -EOPNOTSUPP; in ifi_canfd_set_mode()
820 ret = request_irq(ndev->irq, ifi_canfd_isr, IRQF_SHARED, in ifi_canfd_open()
821 ndev->name, ndev); in ifi_canfd_open()
829 napi_enable(&priv->napi); in ifi_canfd_open()
843 napi_disable(&priv->napi); in ifi_canfd_close()
847 free_irq(ndev->irq, ndev); in ifi_canfd_close()
858 struct canfd_frame *cf = (struct canfd_frame *)skb->data; in ifi_canfd_start_xmit()
866 txst = readl(priv->base + IFI_CANFD_TXSTCMD); in ifi_canfd_start_xmit()
875 if (cf->can_id & CAN_EFF_FLAG) { in ifi_canfd_start_xmit()
876 txid = cf->can_id & CAN_EFF_MASK; in ifi_canfd_start_xmit()
888 txid = cf->can_id & CAN_SFF_MASK; in ifi_canfd_start_xmit()
891 txdlc = can_fd_len2dlc(cf->len); in ifi_canfd_start_xmit()
892 if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { in ifi_canfd_start_xmit()
894 if (cf->flags & CANFD_BRS) in ifi_canfd_start_xmit()
898 if (cf->can_id & CAN_RTR_FLAG) in ifi_canfd_start_xmit()
902 writel(txid, priv->base + IFI_CANFD_TXFIFO_ID); in ifi_canfd_start_xmit()
903 writel(txdlc, priv->base + IFI_CANFD_TXFIFO_DLC); in ifi_canfd_start_xmit()
905 for (i = 0; i < cf->len; i += 4) { in ifi_canfd_start_xmit()
906 writel(*(u32 *)(cf->data + i), in ifi_canfd_start_xmit()
907 priv->base + IFI_CANFD_TXFIFO_DATA + i); in ifi_canfd_start_xmit()
910 writel(0, priv->base + IFI_CANFD_TXFIFO_REPEATCOUNT); in ifi_canfd_start_xmit()
911 writel(0, priv->base + IFI_CANFD_TXFIFO_SUSPEND_US); in ifi_canfd_start_xmit()
916 writel(IFI_CANFD_TXSTCMD_ADD_MSG, priv->base + IFI_CANFD_TXSTCMD); in ifi_canfd_start_xmit()
934 struct device *dev = &pdev->dev; in ifi_canfd_plat_probe()
947 return -EINVAL; in ifi_canfd_plat_probe()
951 dev_err(dev, "This block is not IFI CANFD, id=%08x\n", id); in ifi_canfd_plat_probe()
952 return -EINVAL; in ifi_canfd_plat_probe()
959 return -EINVAL; in ifi_canfd_plat_probe()
964 return -ENOMEM; in ifi_canfd_plat_probe()
966 ndev->irq = irq; in ifi_canfd_plat_probe()
967 ndev->flags |= IFF_ECHO; /* we support local echo */ in ifi_canfd_plat_probe()
968 ndev->netdev_ops = &ifi_canfd_netdev_ops; in ifi_canfd_plat_probe()
969 ndev->ethtool_ops = &ifi_canfd_ethtool_ops; in ifi_canfd_plat_probe()
972 priv->ndev = ndev; in ifi_canfd_plat_probe()
973 priv->base = addr; in ifi_canfd_plat_probe()
975 netif_napi_add(ndev, &priv->napi, ifi_canfd_poll); in ifi_canfd_plat_probe()
977 priv->can.state = CAN_STATE_STOPPED; in ifi_canfd_plat_probe()
979 priv->can.clock.freq = readl(addr + IFI_CANFD_CANCLOCK); in ifi_canfd_plat_probe()
981 priv->can.bittiming_const = &ifi_canfd_bittiming_const; in ifi_canfd_plat_probe()
982 priv->can.data_bittiming_const = &ifi_canfd_bittiming_const; in ifi_canfd_plat_probe()
983 priv->can.do_set_mode = ifi_canfd_set_mode; in ifi_canfd_plat_probe()
984 priv->can.do_get_berr_counter = ifi_canfd_get_berr_counter; in ifi_canfd_plat_probe()
986 /* IFI CANFD can do both Bosch FD and ISO FD */ in ifi_canfd_plat_probe()
987 priv->can.ctrlmode = CAN_CTRLMODE_FD; in ifi_canfd_plat_probe()
989 /* IFI CANFD can do both Bosch FD and ISO FD */ in ifi_canfd_plat_probe()
990 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | in ifi_canfd_plat_probe()
1006 priv->base, ndev->irq, priv->can.clock.freq); in ifi_canfd_plat_probe()
1025 { .compatible = "ifi,canfd-1.0", .data = NULL },
1043 MODULE_DESCRIPTION("CAN bus driver for IFI CANFD controller");