if (!(priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_6)) return 0;
/* Erratum 6: Extended frames may be send as standard frames. * * Not affected if: * - TX'ed a standard frame -or- * - RX'ed an extended frame
*/ if (!(cfd_nominal->can_id & CAN_EFF_FLAG) ||
(cfd_rx->can_id & CAN_EFF_FLAG)) return 0;
/* Not affected if: * - standard part and RTR flag of the TX'ed frame * is not equal the CAN-ID and RTR flag of the RX'ed frame.
*/ if ((cfd_nominal->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK)) !=
(cfd_rx->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK))) return 0;
/* Not affected if: * - length is not the same
*/ if (cfd_nominal->len != cfd_rx->len) return 0;
/* Not affected if: * - the data of non RTR frames is different
*/ if (!(cfd_nominal->can_id & CAN_RTR_FLAG) &&
memcmp(cfd_nominal->data, cfd_rx->data, cfd_nominal->len)) return 0;
/* Affected by Erratum 6 */
u64_stats_update_begin(&rkcanfd_stats->syncp);
u64_stats_inc(&rkcanfd_stats->tx_extended_as_standard_errors);
u64_stats_update_end(&rkcanfd_stats->syncp);
/* Manual handling of CAN Bus Error counters. See * rkcanfd_get_corrected_berr_counter() for detailed * explanation.
*/ if (priv->bec.txerr)
priv->bec.txerr--;
*tx_done = true;
stats->tx_packets++;
stats->tx_errors++;
rkcanfd_xmit_retry(priv);
return 0;
}
staticinlinebool
rkcanfd_fifo_header_empty(conststruct rkcanfd_fifo_header *header)
{ /* Erratum 5: If the FIFO is empty, we read the same value for * all elements.
*/ return header->frameinfo == header->id &&
header->frameinfo == header->ts;
}
/* read header into separate struct and convert it later */
rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
header, sizeof(*header)); /* read data directly into cfd */
rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
cfd->data, sizeof(cfd->data));
/* Erratum 5: Counters for TXEFIFO and RXFIFO may be wrong */ if (rkcanfd_fifo_header_empty(header)) { struct rkcanfd_stats *rkcanfd_stats = &priv->stats;
len = rkcanfd_fifo_header_to_cfd_header(priv, header, cfd);
/* Drop any received CAN-FD frames if CAN-FD mode is not * requested.
*/ if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF &&
!(priv->can.ctrlmode & CAN_CTRLMODE_FD)) {
stats->rx_dropped++;
return 0;
}
if (rkcanfd_get_tx_pending(priv)) { bool tx_done = false;
err = rkcanfd_rxstx_filter(priv, cfd, header->ts, &tx_done); if (err) return err; if (tx_done && !(priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) return 0;
}
/* Manual handling of CAN Bus Error counters. See * rkcanfd_get_corrected_berr_counter() for detailed * explanation.
*/ if (priv->bec.rxerr)
priv->bec.rxerr = min(CAN_ERROR_PASSIVE_THRESHOLD,
priv->bec.rxerr) - 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.