Lines Matching +full:tx +full:- +full:ts +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2015 - 2016 Thomas Körper, esd electronic system design gmbh
3 * Copyright (C) 2017 - 2023 Stefan Mätje, esd electronics gmbh
20 #define ACC_DLC_SSTX_FLAG BIT(24) /* Single Shot TX */
39 /* Two bit wide command masks to mask or unmask a single core IRQ */
73 /* CAN id must be written at last. This write starts TX. */ in acc_txq_put()
80 if (tx_fifo_idx >= core->tx_fifo_size) in acc_tx_fifo_next()
100 static ktime_t acc_ts2ktime(struct acc_ov *ov, u64 ts) in acc_ts2ktime() argument
104 ns = (ts * ACC_TS_FACTOR) + (ts >> ACC_TS_80MHZ_SHIFT); in acc_ts2ktime()
117 ov->version = temp; in acc_init_ov()
118 ov->features = (temp >> 16); in acc_init_ov()
121 ov->total_cores = temp; in acc_init_ov()
122 ov->active_cores = (temp >> 8); in acc_init_ov()
124 ov->core_frequency = acc_ov_read32(ov, ACC_OV_OF_CANCORE_FREQ); in acc_init_ov()
125 ov->timestamp_frequency = acc_ov_read32(ov, ACC_OV_OF_TS_FREQ_LO); in acc_init_ov()
130 if (ov->features & ACC_OV_REG_FEAT_MASK_NEW_PSC) { in acc_init_ov()
134 ov->core_frequency /= 2; in acc_init_ov()
139 ov->version, ov->core_frequency, ov->timestamp_frequency, in acc_init_ov()
140 ov->features, acc_ov_read32(ov, ACC_OV_OF_INFO) >> 16, in acc_init_ov()
141 ov->active_cores, ov->total_cores); in acc_init_ov()
149 * implemented in the FPGA, i.e. N = ov->total_cores in acc_init_bm_ptr()
152 * ---------------------------------------------- in acc_init_bm_ptr()
162 ov->bmfifo.messages = mem; in acc_init_bm_ptr()
163 ov->bmfifo.irq_cnt = mem + (ov->total_cores + 1U) * ACC_CORE_DMABUF_SIZE; in acc_init_bm_ptr()
165 for (u = 0U; u < ov->active_cores; u++) { in acc_init_bm_ptr()
168 core->bmfifo.messages = mem + (u + 1U) * ACC_CORE_DMABUF_SIZE; in acc_init_bm_ptr()
169 core->bmfifo.irq_cnt = ov->bmfifo.irq_cnt + (u + 1U); in acc_init_bm_ptr()
176 struct acc_core *core = priv->core; in acc_open()
182 if (priv->can.state != CAN_STATE_STOPPED) { in acc_open()
184 __func__, can_get_state_str(priv->can.state)); in acc_open()
186 priv->can.state = CAN_STATE_STOPPED; in acc_open()
199 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) in acc_open()
202 if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) in acc_open()
208 priv->can.state = CAN_STATE_ERROR_ACTIVE; in acc_open()
210 /* Resync TX FIFO indices to HW state after (re-)start. */ in acc_open()
212 core->tx_fifo_head = tx_fifo_status & 0xff; in acc_open()
213 core->tx_fifo_tail = (tx_fifo_status >> 8) & 0xff; in acc_open()
222 struct acc_core *core = priv->core; in acc_close()
234 priv->can.state = CAN_STATE_STOPPED; in acc_close()
236 /* Mark pending TX requests to be aborted after controller restart. */ in acc_close()
250 struct acc_core *core = priv->core; in acc_start_xmit()
251 struct can_frame *cf = (struct can_frame *)skb->data; in acc_start_xmit()
252 u8 tx_fifo_head = core->tx_fifo_head; in acc_start_xmit()
260 /* Access core->tx_fifo_tail only once because it may be changed in acc_start_xmit()
263 fifo_usage = tx_fifo_head - core->tx_fifo_tail; in acc_start_xmit()
265 fifo_usage += core->tx_fifo_size; in acc_start_xmit()
267 if (fifo_usage >= core->tx_fifo_size - 1) { in acc_start_xmit()
268 netdev_err(core->netdev, in acc_start_xmit()
269 "BUG: TX ring full when queue awake!\n"); in acc_start_xmit()
274 if (fifo_usage == core->tx_fifo_size - 2) in acc_start_xmit()
277 acc_dlc = can_get_cc_dlc(cf, priv->can.ctrlmode); in acc_start_xmit()
278 if (cf->can_id & CAN_RTR_FLAG) in acc_start_xmit()
280 if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) in acc_start_xmit()
283 if (cf->can_id & CAN_EFF_FLAG) { in acc_start_xmit()
284 acc_id = cf->can_id & CAN_EFF_MASK; in acc_start_xmit()
287 acc_id = cf->can_id & CAN_SFF_MASK; in acc_start_xmit()
290 can_put_echo_skb(skb, netdev, core->tx_fifo_head, 0); in acc_start_xmit()
292 core->tx_fifo_head = acc_tx_fifo_next(core, tx_fifo_head); in acc_start_xmit()
294 acc_txq_put(core, acc_id, acc_dlc, cf->data); in acc_start_xmit()
303 u32 core_status = acc_read32(priv->core, ACC_CORE_OF_STATUS); in acc_get_berr_counter()
305 bec->txerr = (core_status >> 8) & 0xff; in acc_get_berr_counter()
306 bec->rxerr = core_status & 0xff; in acc_get_berr_counter()
320 acc_read32(priv->core, ACC_CORE_OF_TXFIFO_STATUS); in acc_set_mode()
323 if (hw_fifo_head != priv->core->tx_fifo_head || in acc_set_mode()
324 hw_fifo_head != priv->core->tx_fifo_tail) { in acc_set_mode()
326 "TX FIFO mismatch: T %2u H %2u; TFHW %#08x\n", in acc_set_mode()
327 priv->core->tx_fifo_tail, in acc_set_mode()
328 priv->core->tx_fifo_head, in acc_set_mode()
332 acc_resetmode_leave(priv->core); in acc_set_mode()
333 /* To leave the bus-off state the esdACC controller begins in acc_set_mode()
338 * During this time the TX FIFO may still contain already in acc_set_mode()
344 * the error-active state again, it informs us about that in acc_set_mode()
352 return -EOPNOTSUPP; in acc_set_mode()
361 const struct can_bittiming *bt = &priv->can.bittiming; in acc_set_bittiming()
365 if (priv->ov->features & ACC_OV_REG_FEAT_MASK_CANFD) { in acc_set_bittiming()
369 bt->brp, bt->prop_seg, in acc_set_bittiming()
370 bt->phase_seg1, bt->phase_seg2, bt->sjw); in acc_set_bittiming()
372 brp = FIELD_PREP(ACC_REG_BRP_FD_MASK_BRP, bt->brp - 1); in acc_set_bittiming()
374 btr = FIELD_PREP(ACC_REG_BTR_FD_MASK_TSEG1, bt->phase_seg1 + bt->prop_seg - 1); in acc_set_bittiming()
375 btr |= FIELD_PREP(ACC_REG_BTR_FD_MASK_TSEG2, bt->phase_seg2 - 1); in acc_set_bittiming()
376 btr |= FIELD_PREP(ACC_REG_BTR_FD_MASK_SJW, bt->sjw - 1); in acc_set_bittiming()
379 acc_write32(priv->core, ACC_CORE_OF_BRP, brp); in acc_set_bittiming()
380 acc_write32(priv->core, ACC_CORE_OF_BTR, btr); in acc_set_bittiming()
386 bt->brp, bt->prop_seg, in acc_set_bittiming()
387 bt->phase_seg1, bt->phase_seg2, bt->sjw); in acc_set_bittiming()
389 brp = FIELD_PREP(ACC_REG_BRP_CL_MASK_BRP, bt->brp - 1); in acc_set_bittiming()
391 btr = FIELD_PREP(ACC_REG_BTR_CL_MASK_TSEG1, bt->phase_seg1 + bt->prop_seg - 1); in acc_set_bittiming()
392 btr |= FIELD_PREP(ACC_REG_BTR_CL_MASK_TSEG2, bt->phase_seg2 - 1); in acc_set_bittiming()
393 btr |= FIELD_PREP(ACC_REG_BTR_CL_MASK_SJW, bt->sjw - 1); in acc_set_bittiming()
396 acc_write32(priv->core, ACC_CORE_OF_BRP, brp); in acc_set_bittiming()
397 acc_write32(priv->core, ACC_CORE_OF_BTR, btr); in acc_set_bittiming()
408 struct acc_net_priv *priv = netdev_priv(core->netdev); in handle_core_msg_rxtxdone()
409 struct net_device_stats *stats = &core->netdev->stats; in handle_core_msg_rxtxdone()
412 if (msg->acc_dlc.len & ACC_DLC_TXD_FLAG) { in handle_core_msg_rxtxdone()
413 u8 tx_fifo_tail = core->tx_fifo_tail; in handle_core_msg_rxtxdone()
415 if (core->tx_fifo_head == tx_fifo_tail) { in handle_core_msg_rxtxdone()
416 netdev_warn(core->netdev, in handle_core_msg_rxtxdone()
417 "TX interrupt, but queue is empty!?\n"); in handle_core_msg_rxtxdone()
422 skb = priv->can.echo_skb[tx_fifo_tail]; in handle_core_msg_rxtxdone()
424 skb_hwtstamps(skb)->hwtstamp = in handle_core_msg_rxtxdone()
425 acc_ts2ktime(priv->ov, msg->ts); in handle_core_msg_rxtxdone()
428 stats->tx_packets++; in handle_core_msg_rxtxdone()
429 stats->tx_bytes += can_get_echo_skb(core->netdev, tx_fifo_tail, in handle_core_msg_rxtxdone()
432 core->tx_fifo_tail = acc_tx_fifo_next(core, tx_fifo_tail); in handle_core_msg_rxtxdone()
434 netif_wake_queue(core->netdev); in handle_core_msg_rxtxdone()
439 skb = alloc_can_skb(core->netdev, &cf); in handle_core_msg_rxtxdone()
441 stats->rx_dropped++; in handle_core_msg_rxtxdone()
445 cf->can_id = msg->id & ACC_ID_ID_MASK; in handle_core_msg_rxtxdone()
446 if (msg->id & ACC_ID_EFF_FLAG) in handle_core_msg_rxtxdone()
447 cf->can_id |= CAN_EFF_FLAG; in handle_core_msg_rxtxdone()
449 can_frame_set_cc_len(cf, msg->acc_dlc.len & ACC_DLC_DLC_MASK, in handle_core_msg_rxtxdone()
450 priv->can.ctrlmode); in handle_core_msg_rxtxdone()
452 if (msg->acc_dlc.len & ACC_DLC_RTR_FLAG) { in handle_core_msg_rxtxdone()
453 cf->can_id |= CAN_RTR_FLAG; in handle_core_msg_rxtxdone()
455 memcpy(cf->data, msg->data, cf->len); in handle_core_msg_rxtxdone()
456 stats->rx_bytes += cf->len; in handle_core_msg_rxtxdone()
458 stats->rx_packets++; in handle_core_msg_rxtxdone()
460 skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts); in handle_core_msg_rxtxdone()
469 struct net_device_stats *stats = &core->netdev->stats; in handle_core_msg_txabort()
470 u8 tx_fifo_tail = core->tx_fifo_tail; in handle_core_msg_txabort()
471 u32 abort_mask = msg->abort_mask; /* u32 extend to avoid warnings later */ in handle_core_msg_txabort()
474 while (tx_fifo_tail != core->tx_fifo_head && (abort_mask)) { in handle_core_msg_txabort()
481 can_free_echo_skb(core->netdev, tx_fifo_tail, NULL); in handle_core_msg_txabort()
482 stats->tx_dropped++; in handle_core_msg_txabort()
483 stats->tx_aborted_errors++; in handle_core_msg_txabort()
487 core->tx_fifo_tail = tx_fifo_tail; in handle_core_msg_txabort()
489 netdev_warn(core->netdev, "Unhandled aborted messages\n"); in handle_core_msg_txabort()
492 netif_wake_queue(core->netdev); in handle_core_msg_txabort()
498 struct acc_net_priv *priv = netdev_priv(core->netdev); in handle_core_msg_overrun()
499 struct net_device_stats *stats = &core->netdev->stats; in handle_core_msg_overrun()
504 if (msg->lost_cnt) { in handle_core_msg_overrun()
505 stats->rx_errors += msg->lost_cnt; in handle_core_msg_overrun()
506 stats->rx_over_errors += msg->lost_cnt; in handle_core_msg_overrun()
508 stats->rx_errors++; in handle_core_msg_overrun()
509 stats->rx_over_errors++; in handle_core_msg_overrun()
512 skb = alloc_can_err_skb(core->netdev, &cf); in handle_core_msg_overrun()
516 cf->can_id |= CAN_ERR_CRTL; in handle_core_msg_overrun()
517 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; in handle_core_msg_overrun()
519 skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts); in handle_core_msg_overrun()
527 struct acc_net_priv *priv = netdev_priv(core->netdev); in handle_core_msg_buserr()
528 struct net_device_stats *stats = &core->netdev->stats; in handle_core_msg_buserr()
531 const u32 reg_status = msg->reg_status; in handle_core_msg_buserr()
536 priv->can.can_stats.bus_error++; in handle_core_msg_buserr()
539 if (msg->ecc & ACC_ECC_DIR) { in handle_core_msg_buserr()
540 stats->rx_errors++; in handle_core_msg_buserr()
543 stats->tx_errors++; in handle_core_msg_buserr()
546 switch (msg->ecc & ACC_ECC_MASK) { in handle_core_msg_buserr()
561 skb = alloc_can_err_skb(core->netdev, &cf); in handle_core_msg_buserr()
565 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT; in handle_core_msg_buserr()
568 cf->data[2] = can_err_prot_type; in handle_core_msg_buserr()
570 cf->data[3] = msg->ecc & ACC_ECC_SEG; in handle_core_msg_buserr()
572 /* Insert CAN TX and RX error counters. */ in handle_core_msg_buserr()
573 cf->data[6] = txerr; in handle_core_msg_buserr()
574 cf->data[7] = rxerr; in handle_core_msg_buserr()
576 skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts); in handle_core_msg_buserr()
585 struct acc_net_priv *priv = netdev_priv(core->netdev); in handle_core_msg_errstatechange()
588 const u32 reg_status = msg->reg_status; in handle_core_msg_errstatechange()
601 if (priv->can.state == CAN_STATE_BUS_OFF) { in handle_core_msg_errstatechange()
603 netif_wake_queue(core->netdev); in handle_core_msg_errstatechange()
607 skb = alloc_can_err_skb(core->netdev, &cf); in handle_core_msg_errstatechange()
609 if (new_state != priv->can.state) { in handle_core_msg_errstatechange()
621 can_change_state(core->netdev, cf, tx_state, rx_state); in handle_core_msg_errstatechange()
625 cf->can_id |= CAN_ERR_CNT; in handle_core_msg_errstatechange()
626 cf->data[6] = txerr; in handle_core_msg_errstatechange()
627 cf->data[7] = rxerr; in handle_core_msg_errstatechange()
629 skb_hwtstamps(skb)->hwtstamp = acc_ts2ktime(priv->ov, msg->ts); in handle_core_msg_errstatechange()
636 can_bus_off(core->netdev); in handle_core_msg_errstatechange()
642 u32 msg_fifo_head = core->bmfifo.local_irq_cnt & 0xff; in handle_core_interrupt()
644 while (core->bmfifo.msg_fifo_tail != msg_fifo_head) { in handle_core_interrupt()
646 &core->bmfifo.messages[core->bmfifo.msg_fifo_tail]; in handle_core_interrupt()
648 switch (msg->msg_id) { in handle_core_interrupt()
650 handle_core_msg_rxtxdone(core, &msg->rxtxdone); in handle_core_interrupt()
654 handle_core_msg_txabort(core, &msg->txabort); in handle_core_interrupt()
658 handle_core_msg_overrun(core, &msg->overrun); in handle_core_interrupt()
662 handle_core_msg_buserr(core, &msg->buserr); in handle_core_interrupt()
668 &msg->errstatechange); in handle_core_interrupt()
672 /* Ignore all other BM messages (like the CAN-FD messages) */ in handle_core_interrupt()
676 core->bmfifo.msg_fifo_tail = in handle_core_interrupt()
677 (core->bmfifo.msg_fifo_tail + 1) & 0xff; in handle_core_interrupt()
682 * acc_card_interrupt() - handle the interrupts of an esdACC FPGA
695 * The pending interrupts are masked by writing to the IRQ mask register at
702 * ACC_BM_IRQ_MASK, 10: mask interrupt
727 if (READ_ONCE(*ov->bmfifo.irq_cnt) != ov->bmfifo.local_irq_cnt) { in acc_card_interrupt()
729 ov->bmfifo.local_irq_cnt = READ_ONCE(*ov->bmfifo.irq_cnt); in acc_card_interrupt()
732 for (i = 0; i < ov->active_cores; i++) { in acc_card_interrupt()
735 if (READ_ONCE(*core->bmfifo.irq_cnt) != core->bmfifo.local_irq_cnt) { in acc_card_interrupt()
737 core->bmfifo.local_irq_cnt = READ_ONCE(*core->bmfifo.irq_cnt); in acc_card_interrupt()
751 /* handle_ov_interrupt(); - no use yet. */ in acc_card_interrupt()
753 ov->bmfifo.local_irq_cnt); in acc_card_interrupt()
756 for (i = 0; i < ov->active_cores; i++) { in acc_card_interrupt()
762 core->bmfifo.local_irq_cnt); in acc_card_interrupt()