Lines Matching +full:ctu +full:-

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * CTU CAN FD IP Core
6 * Copyright (C) 2015-2018 Ondrej Ille <[email protected]> FEE CTU
7 * Copyright (C) 2018-2021 Ondrej Ille <[email protected]> self-funded
8 * Copyright (C) 2018-2019 Martin Jerabek <[email protected]> FEE CTU
9 * Copyright (C) 2018-2022 Pavel Pisa <[email protected]> FEE CTU/self-funded
49 * - when a buffer transitions to empty state, rotate order and priorities
50 * - if more buffers seem to transition at the same time, rotate by the number of buffers
51 * - it may be assumed that buffers transition to empty state in FIFO order (because we manage
53 * - at frame filling, do not rotate anything, just increment buffer modulo counter
114 iowrite32(val, priv->mem_base + reg); in ctucan_write32_le()
120 iowrite32be(val, priv->mem_base + reg); in ctucan_write32_be()
126 return ioread32(priv->mem_base + reg); in ctucan_read32_le()
132 return ioread32be(priv->mem_base + reg); in ctucan_read32_be()
137 priv->write_reg(priv, reg, val); in ctucan_write32()
142 return priv->read_reg(priv, reg); in ctucan_read32()
148 priv->write_reg(priv, buf_base + offset, val); in ctucan_write_txt_buf()
155 * ctucan_state_to_str() - Converts CAN controller state code to corresponding text
170 * ctucan_reset() - Issues software reset request to CTU CAN FD
173 * Return: 0 for success, -%ETIMEDOUT if CAN controller does not leave reset
181 clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_reset()
189 if (!i--) { in ctucan_reset()
191 return -ETIMEDOUT; in ctucan_reset()
198 * ctucan_set_btr() - Sets CAN bus bit timing in CTU CAN FD
201 * @nominal: True - Nominal bit timing, False - Data bit timing
203 * Return: 0 - OK, -%EPERM if controller is enabled
210 u32 prop_seg = bt->prop_seg; in ctucan_set_btr()
211 u32 phase_seg1 = bt->phase_seg1; in ctucan_set_btr()
214 netdev_err(ndev, "BUG! Cannot set bittiming - CAN is enabled\n"); in ctucan_set_btr()
215 return -EPERM; in ctucan_set_btr()
223 * In CTU CAN FD, PROP is 6/7 bits wide but PH1 only 6/5, so we must re-distribute the in ctucan_set_btr()
227 prop_seg += phase_seg1 - max_ph1_len; in ctucan_set_btr()
229 bt->prop_seg = prop_seg; in ctucan_set_btr()
230 bt->phase_seg1 = phase_seg1; in ctucan_set_btr()
236 btr |= FIELD_PREP(REG_BTR_PH2, bt->phase_seg2); in ctucan_set_btr()
237 btr |= FIELD_PREP(REG_BTR_BRP, bt->brp); in ctucan_set_btr()
238 btr |= FIELD_PREP(REG_BTR_SJW, bt->sjw); in ctucan_set_btr()
244 btr |= FIELD_PREP(REG_BTR_FD_PH2_FD, bt->phase_seg2); in ctucan_set_btr()
245 btr |= FIELD_PREP(REG_BTR_FD_BRP_FD, bt->brp); in ctucan_set_btr()
246 btr |= FIELD_PREP(REG_BTR_FD_SJW_FD, bt->sjw); in ctucan_set_btr()
255 * ctucan_set_bittiming() - CAN set nominal bit timing routine
258 * Return: 0 on success, -%EPERM on error
263 struct can_bittiming *bt = &priv->can.bittiming; in ctucan_set_bittiming()
270 * ctucan_set_data_bittiming() - CAN set data bit timing routine
273 * Return: 0 on success, -%EPERM on error
278 struct can_bittiming *dbt = &priv->can.data_bittiming; in ctucan_set_data_bittiming()
285 * ctucan_set_secondary_sample_point() - Sets secondary sample point in CTU CAN FD
288 * Return: 0 on success, -%EPERM if controller is enabled
293 struct can_bittiming *dbt = &priv->can.data_bittiming; in ctucan_set_secondary_sample_point()
298 netdev_err(ndev, "BUG! Cannot set SSP - CAN is enabled\n"); in ctucan_set_secondary_sample_point()
299 return -EPERM; in ctucan_set_secondary_sample_point()
302 /* Use SSP for bit-rates above 1 Mbits/s */ in ctucan_set_secondary_sample_point()
303 if (dbt->bitrate > 1000000) { in ctucan_set_secondary_sample_point()
305 ssp_offset = (priv->can.clock.freq / 1000) * dbt->sample_point / dbt->bitrate; in ctucan_set_secondary_sample_point()
322 * ctucan_set_mode() - Sets CTU CAN FDs mode
330 mode_reg = (mode->flags & CAN_CTRLMODE_LOOPBACK) ? in ctucan_set_mode()
334 mode_reg = (mode->flags & CAN_CTRLMODE_LISTENONLY) ? in ctucan_set_mode()
338 mode_reg = (mode->flags & CAN_CTRLMODE_FD) ? in ctucan_set_mode()
342 mode_reg = (mode->flags & CAN_CTRLMODE_PRESUME_ACK) ? in ctucan_set_mode()
346 mode_reg = (mode->flags & CAN_CTRLMODE_FD_NON_ISO) ? in ctucan_set_mode()
352 mode_reg = (mode->flags & CAN_CTRLMODE_ONE_SHOT) ? in ctucan_set_mode()
357 * TSTM - Off, User shall not be able to change REC/TEC by hand during operation in ctucan_set_mode()
365 * ctucan_chip_start() - This routine starts the driver
383 priv->txb_prio = 0x01234567; in ctucan_chip_start()
384 priv->txb_head = 0; in ctucan_chip_start()
385 priv->txb_tail = 0; in ctucan_chip_start()
386 ctucan_write32(priv, CTUCANFD_TX_PRIORITY, priv->txb_prio); in ctucan_chip_start()
388 /* Configure bit-rates and ssp */ in ctucan_chip_start()
402 mode.flags = priv->can.ctrlmode; in ctucan_chip_start()
412 /* Bus error reporting -> Allow Error/Arb.lost interrupts */ in ctucan_chip_start()
413 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { in ctucan_chip_start()
425 priv->can.state = CAN_STATE_STOPPED; in ctucan_chip_start()
436 * ctucan_do_set_mode() - Sets mode of the driver
461 ret = -EOPNOTSUPP; in ctucan_do_set_mode()
469 * ctucan_get_tx_status() - Gets status of TXT buffer
471 * @buf: Buffer index (0-based)
484 * ctucan_is_txt_buf_writable() - Checks if frame can be inserted to TXT Buffer
486 * @buf: Buffer index (0-based)
488 * Return: True - Frame can be inserted to TXT Buffer, False - If attempted, frame will not be
503 * ctucan_insert_frame() - Inserts frame to TXT buffer
506 * @buf: TXT Buffer index to which frame is inserted (0-based)
507 * @isfdf: True - CAN FD Frame, False - CAN 2.0 Frame
509 * Return: True - Frame inserted successfully
510 * False - Frame was not inserted due to one of:
523 if (buf >= priv->ntxbufs) in ctucan_insert_frame()
529 if (cf->len > CANFD_MAX_DLEN) in ctucan_insert_frame()
533 if (cf->can_id & CAN_RTR_FLAG) in ctucan_insert_frame()
536 if (cf->can_id & CAN_EFF_FLAG) in ctucan_insert_frame()
541 if (cf->flags & CANFD_BRS) in ctucan_insert_frame()
545 ffw |= FIELD_PREP(REG_FRAME_FORMAT_W_DLC, can_fd_len2dlc(cf->len)); in ctucan_insert_frame()
548 if (cf->can_id & CAN_EFF_FLAG) in ctucan_insert_frame()
549 idw = cf->can_id & CAN_EFF_MASK; in ctucan_insert_frame()
551 idw = FIELD_PREP(REG_IDENTIFIER_W_IDENTIFIER_BASE, cf->can_id & CAN_SFF_MASK); in ctucan_insert_frame()
553 /* Write ID, Frame format, Don't write timestamp -> Time triggered transmission disabled */ in ctucan_insert_frame()
559 if (!(cf->can_id & CAN_RTR_FLAG)) { in ctucan_insert_frame()
560 for (i = 0; i < cf->len; i += 4) { in ctucan_insert_frame()
561 u32 data = le32_to_cpu(*(__le32 *)(cf->data + i)); in ctucan_insert_frame()
571 * ctucan_give_txtb_cmd() - Applies command on TXT buffer
574 * @buf: Buffer index (0-based)
585 * ctucan_start_xmit() - Starts the transmission
598 struct canfd_frame *cf = (struct canfd_frame *)skb->data; in ctucan_start_xmit()
612 txtb_id = priv->txb_head % priv->ntxbufs; in ctucan_start_xmit()
619 ndev->stats.tx_dropped++; in ctucan_start_xmit()
625 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_start_xmit()
627 priv->txb_head++; in ctucan_start_xmit()
633 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_start_xmit()
639 * ctucan_read_rx_frame() - Reads frame from RX FIFO
640 * @priv: Pointer to CTU CAN FD's private data
655 cf->can_id = (idw & CAN_EFF_MASK) | CAN_EFF_FLAG; in ctucan_read_rx_frame()
657 cf->can_id = (idw >> 18) & CAN_SFF_MASK; in ctucan_read_rx_frame()
662 cf->flags |= CANFD_BRS; in ctucan_read_rx_frame()
664 cf->flags |= CANFD_ESI; in ctucan_read_rx_frame()
666 cf->can_id |= CAN_RTR_FLAG; in ctucan_read_rx_frame()
669 wc = FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw) - 3; in ctucan_read_rx_frame()
680 cf->len = len; in ctucan_read_rx_frame()
684 /* Timestamp - Read and throw away */ in ctucan_read_rx_frame()
691 *(__le32 *)(cf->data + i) = cpu_to_le32(data); in ctucan_read_rx_frame()
700 * ctucan_rx() - Called from CAN ISR to complete the received frame processing
707 * -%EAGAIN in a case of empty Rx FIFO.
712 struct net_device_stats *stats = &ndev->stats; in ctucan_rx()
717 if (test_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags)) { in ctucan_rx()
718 ffw = priv->rxfrm_first_word; in ctucan_rx()
719 clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_rx()
725 return -EAGAIN; in ctucan_rx()
733 priv->rxfrm_first_word = ffw; in ctucan_rx()
734 set_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags); in ctucan_rx()
740 stats->rx_bytes += cf->len; in ctucan_rx()
741 stats->rx_packets++; in ctucan_rx()
748 * ctucan_read_fault_state() - Reads CTU CAN FDs fault confinement state.
780 * ctucan_get_rec_tec() - Reads REC/TEC counter values from controller
788 bec->rxerr = FIELD_GET(REG_REC_REC_VAL, err_ctrs); in ctucan_get_rec_tec()
789 bec->txerr = FIELD_GET(REG_REC_TEC_VAL, err_ctrs); in ctucan_get_rec_tec()
793 * ctucan_err_interrupt() - Error frame ISR
803 struct net_device_stats *stats = &ndev->stats; in ctucan_err_interrupt()
832 ctucan_state_to_str(priv->can.state), in ctucan_err_interrupt()
835 if (priv->can.state == state) in ctucan_err_interrupt()
839 priv->can.state = state; in ctucan_err_interrupt()
842 priv->can.can_stats.bus_off++; in ctucan_err_interrupt()
845 cf->can_id |= CAN_ERR_BUSOFF; in ctucan_err_interrupt()
848 priv->can.can_stats.error_passive++; in ctucan_err_interrupt()
850 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ctucan_err_interrupt()
851 cf->data[1] = (bec.rxerr > 127) ? in ctucan_err_interrupt()
854 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
855 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
859 priv->can.can_stats.error_warning++; in ctucan_err_interrupt()
861 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ctucan_err_interrupt()
862 cf->data[1] |= (bec.txerr > bec.rxerr) ? in ctucan_err_interrupt()
865 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
866 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
871 cf->can_id |= CAN_ERR_CNT; in ctucan_err_interrupt()
872 cf->data[1] = CAN_ERR_CRTL_ACTIVE; in ctucan_err_interrupt()
873 cf->data[6] = bec.txerr; in ctucan_err_interrupt()
874 cf->data[7] = bec.rxerr; in ctucan_err_interrupt()
888 priv->can.can_stats.arbitration_lost++; in ctucan_err_interrupt()
890 cf->can_id |= CAN_ERR_LOSTARB; in ctucan_err_interrupt()
891 cf->data[0] = CAN_ERR_LOSTARB_UNSPEC; in ctucan_err_interrupt()
898 priv->can.can_stats.bus_error++; in ctucan_err_interrupt()
899 stats->rx_errors++; in ctucan_err_interrupt()
901 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; in ctucan_err_interrupt()
902 cf->data[2] = CAN_ERR_PROT_UNSPEC; in ctucan_err_interrupt()
903 cf->data[3] = CAN_ERR_PROT_LOC_UNSPEC; in ctucan_err_interrupt()
908 stats->rx_packets++; in ctucan_err_interrupt()
909 stats->rx_bytes += cf->can_dlc; in ctucan_err_interrupt()
915 * ctucan_rx_poll() - Poll routine for rx packets (NAPI)
925 struct net_device *ndev = napi->dev; in ctucan_rx_poll()
942 struct net_device_stats *stats = &ndev->stats; in ctucan_rx_poll()
947 stats->rx_over_errors++; in ctucan_rx_poll()
948 stats->rx_errors++; in ctucan_rx_poll()
951 cf->can_id |= CAN_ERR_CRTL; in ctucan_rx_poll()
952 cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; in ctucan_rx_poll()
953 stats->rx_packets++; in ctucan_rx_poll()
954 stats->rx_bytes += cf->can_dlc; in ctucan_rx_poll()
964 /* Clear and enable RBNEI. It is level-triggered, so in ctucan_rx_poll()
976 * ctucan_rotate_txb_prio() - Rotates priorities of TXT Buffers
982 u32 prio = priv->txb_prio; in ctucan_rotate_txb_prio()
984 prio = (prio << 4) | ((prio >> ((priv->ntxbufs - 1) * 4)) & 0xF); in ctucan_rotate_txb_prio()
985 ctucan_netdev_dbg(ndev, "%s: from 0x%08x to 0x%08x\n", __func__, priv->txb_prio, prio); in ctucan_rotate_txb_prio()
986 priv->txb_prio = prio; in ctucan_rotate_txb_prio()
991 * ctucan_tx_interrupt() - Tx done Isr
997 struct net_device_stats *stats = &ndev->stats; in ctucan_tx_interrupt()
1006 * if ok -> echo in ctucan_tx_interrupt()
1007 * if error / aborted -> ?? (find how to handle oneshot mode) in ctucan_tx_interrupt()
1011 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1014 while ((int)(priv->txb_head - priv->txb_tail) > 0) { in ctucan_tx_interrupt()
1015 txtb_id = priv->txb_tail % priv->ntxbufs; in ctucan_tx_interrupt()
1023 stats->tx_bytes += can_get_echo_skb(ndev, txtb_id, NULL); in ctucan_tx_interrupt()
1024 stats->tx_packets++; in ctucan_tx_interrupt()
1034 stats->tx_dropped++; in ctucan_tx_interrupt()
1038 * re-queue the frame, but multiqueue/abort is not supported yet in ctucan_tx_interrupt()
1043 stats->tx_dropped++; in ctucan_tx_interrupt()
1053 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1059 priv->txb_tail++; in ctucan_tx_interrupt()
1067 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1069 /* If no buffers were processed this time, we cannot clear - that would introduce in ctucan_tx_interrupt()
1081 spin_lock_irqsave(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1087 spin_unlock_irqrestore(&priv->tx_lock, flags); in ctucan_tx_interrupt()
1091 * ctucan_interrupt() - CAN Isr
1095 * This is the CTU CAN FD ISR. It checks for the type of interrupt
1099 * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
1125 napi_schedule(&priv->napi); in ctucan_interrupt()
1154 priv->txb_head, priv->txb_tail); in ctucan_interrupt()
1155 for (i = 0; i < priv->ntxbufs; i++) { in ctucan_interrupt()
1170 * ctucan_chip_stop() - Driver stop routine
1189 priv->can.state = CAN_STATE_STOPPED; in ctucan_chip_stop()
1193 * ctucan_open() - Driver open routine
1204 ret = pm_runtime_get_sync(priv->dev); in ctucan_open()
1208 pm_runtime_put_noidle(priv->dev); in ctucan_open()
1223 ret = request_irq(ndev->irq, ctucan_interrupt, priv->irq_flags, ndev->name, ndev); in ctucan_open()
1236 napi_enable(&priv->napi); in ctucan_open()
1242 free_irq(ndev->irq, ndev); in ctucan_open()
1247 pm_runtime_put(priv->dev); in ctucan_open()
1253 * ctucan_close() - Driver close routine
1263 napi_disable(&priv->napi); in ctucan_close()
1265 free_irq(ndev->irq, ndev); in ctucan_close()
1268 pm_runtime_put(priv->dev); in ctucan_close()
1274 * ctucan_get_berr_counter() - error counter routine
1286 ret = pm_runtime_get_sync(priv->dev); in ctucan_get_berr_counter()
1289 pm_runtime_put_noidle(priv->dev); in ctucan_get_berr_counter()
1294 pm_runtime_put(priv->dev); in ctucan_get_berr_counter()
1320 priv->can.state = CAN_STATE_SLEEPING; in ctucan_suspend()
1331 priv->can.state = CAN_STATE_ERROR_ACTIVE; in ctucan_resume()
1353 return -ENOMEM; in ctucan_probe_common()
1356 spin_lock_init(&priv->tx_lock); in ctucan_probe_common()
1357 INIT_LIST_HEAD(&priv->peers_on_pdev); in ctucan_probe_common()
1358 priv->ntxbufs = ntxbufs; in ctucan_probe_common()
1359 priv->dev = dev; in ctucan_probe_common()
1360 priv->can.bittiming_const = &ctu_can_fd_bit_timing_max; in ctucan_probe_common()
1361 priv->can.data_bittiming_const = &ctu_can_fd_bit_timing_data_max; in ctucan_probe_common()
1362 priv->can.do_set_mode = ctucan_do_set_mode; in ctucan_probe_common()
1365 priv->can.do_set_bittiming = ctucan_set_bittiming; in ctucan_probe_common()
1366 priv->can.do_set_data_bittiming = ctucan_set_data_bittiming; in ctucan_probe_common()
1368 priv->can.do_get_berr_counter = ctucan_get_berr_counter; in ctucan_probe_common()
1369 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK in ctucan_probe_common()
1376 priv->mem_base = addr; in ctucan_probe_common()
1379 ndev->irq = irq; in ctucan_probe_common()
1380 ndev->flags |= IFF_ECHO; /* We support local echo */ in ctucan_probe_common()
1385 ndev->netdev_ops = &ctucan_netdev_ops; in ctucan_probe_common()
1386 ndev->ethtool_ops = &ctucan_ethtool_ops; in ctucan_probe_common()
1390 priv->can_clk = devm_clk_get(dev, NULL); in ctucan_probe_common()
1391 if (IS_ERR(priv->can_clk)) { in ctucan_probe_common()
1393 ret = PTR_ERR(priv->can_clk); in ctucan_probe_common()
1396 can_clk_rate = clk_get_rate(priv->can_clk); in ctucan_probe_common()
1399 priv->write_reg = ctucan_write32_le; in ctucan_probe_common()
1400 priv->read_reg = ctucan_read32_le; in ctucan_probe_common()
1408 pm_runtime_put_noidle(priv->dev); in ctucan_probe_common()
1412 /* Check for big-endianity and set according IO-accessors */ in ctucan_probe_common()
1414 priv->write_reg = ctucan_write32_be; in ctucan_probe_common()
1415 priv->read_reg = ctucan_read32_be; in ctucan_probe_common()
1418 ret = -ENODEV; in ctucan_probe_common()
1427 priv->can.clock.freq = can_clk_rate; in ctucan_probe_common()
1429 netif_napi_add(ndev, &priv->napi, ctucan_rx_poll); in ctucan_probe_common()
1440 priv->mem_base, ndev->irq, priv->can.clock.freq, priv->ntxbufs); in ctucan_probe_common()
1445 pm_runtime_put(priv->dev); in ctucan_probe_common()
1450 list_del_init(&priv->peers_on_pdev); in ctucan_probe_common()
1460 MODULE_DESCRIPTION("CTU CAN FD interface");