11e846c7aSMarc Kleine-Budde // SPDX-License-Identifier: GPL-2.0
21e846c7aSMarc Kleine-Budde //
31e846c7aSMarc Kleine-Budde // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
41e846c7aSMarc Kleine-Budde //
51333fd55SMarc Kleine-Budde // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
61e846c7aSMarc Kleine-Budde // Marc Kleine-Budde <kernel@pengutronix.de>
71e846c7aSMarc Kleine-Budde //
81e846c7aSMarc Kleine-Budde // Based on:
91e846c7aSMarc Kleine-Budde //
101e846c7aSMarc Kleine-Budde // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
111e846c7aSMarc Kleine-Budde //
121e846c7aSMarc Kleine-Budde // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
131e846c7aSMarc Kleine-Budde //
141e846c7aSMarc Kleine-Budde
151e846c7aSMarc Kleine-Budde #include <linux/bitfield.h>
161e846c7aSMarc Kleine-Budde
171e846c7aSMarc Kleine-Budde #include "mcp251xfd.h"
181e846c7aSMarc Kleine-Budde
mcp251xfd_tx_fifo_sta_empty(u32 fifo_sta)1991017ba4SMarc Kleine-Budde static inline bool mcp251xfd_tx_fifo_sta_empty(u32 fifo_sta)
201333fd55SMarc Kleine-Budde {
2191017ba4SMarc Kleine-Budde return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF;
221333fd55SMarc Kleine-Budde }
231333fd55SMarc Kleine-Budde
mcp251xfd_tx_fifo_sta_less_than_half_full(u32 fifo_sta)24*50d66c86SMarc Kleine-Budde static inline bool mcp251xfd_tx_fifo_sta_less_than_half_full(u32 fifo_sta)
25*50d66c86SMarc Kleine-Budde {
26*50d66c86SMarc Kleine-Budde return fifo_sta & MCP251XFD_REG_FIFOSTA_TFHRFHIF;
27*50d66c86SMarc Kleine-Budde }
28*50d66c86SMarc Kleine-Budde
291e846c7aSMarc Kleine-Budde static inline int
mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv * priv,u8 * tef_tail)301e846c7aSMarc Kleine-Budde mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv,
311e846c7aSMarc Kleine-Budde u8 *tef_tail)
321e846c7aSMarc Kleine-Budde {
331e846c7aSMarc Kleine-Budde u32 tef_ua;
341e846c7aSMarc Kleine-Budde int err;
351e846c7aSMarc Kleine-Budde
361e846c7aSMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFUA, &tef_ua);
371e846c7aSMarc Kleine-Budde if (err)
381e846c7aSMarc Kleine-Budde return err;
391e846c7aSMarc Kleine-Budde
401e846c7aSMarc Kleine-Budde *tef_tail = tef_ua / sizeof(struct mcp251xfd_hw_tef_obj);
411e846c7aSMarc Kleine-Budde
421e846c7aSMarc Kleine-Budde return 0;
431e846c7aSMarc Kleine-Budde }
441e846c7aSMarc Kleine-Budde
mcp251xfd_check_tef_tail(const struct mcp251xfd_priv * priv)451e846c7aSMarc Kleine-Budde static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv)
461e846c7aSMarc Kleine-Budde {
471e846c7aSMarc Kleine-Budde u8 tef_tail_chip, tef_tail;
481e846c7aSMarc Kleine-Budde int err;
491e846c7aSMarc Kleine-Budde
501e846c7aSMarc Kleine-Budde if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY))
511e846c7aSMarc Kleine-Budde return 0;
521e846c7aSMarc Kleine-Budde
531e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_tail_get_from_chip(priv, &tef_tail_chip);
541e846c7aSMarc Kleine-Budde if (err)
551e846c7aSMarc Kleine-Budde return err;
561e846c7aSMarc Kleine-Budde
571e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv);
581e846c7aSMarc Kleine-Budde if (tef_tail_chip != tef_tail) {
591e846c7aSMarc Kleine-Budde netdev_err(priv->ndev,
601e846c7aSMarc Kleine-Budde "TEF tail of chip (0x%02x) and ours (0x%08x) inconsistent.\n",
611e846c7aSMarc Kleine-Budde tef_tail_chip, tef_tail);
621e846c7aSMarc Kleine-Budde return -EILSEQ;
631e846c7aSMarc Kleine-Budde }
641e846c7aSMarc Kleine-Budde
651e846c7aSMarc Kleine-Budde return 0;
661e846c7aSMarc Kleine-Budde }
671e846c7aSMarc Kleine-Budde
681e846c7aSMarc Kleine-Budde static int
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv * priv,const struct mcp251xfd_hw_tef_obj * hw_tef_obj,unsigned int * frame_len_ptr)691e846c7aSMarc Kleine-Budde mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
701e846c7aSMarc Kleine-Budde const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
711e846c7aSMarc Kleine-Budde unsigned int *frame_len_ptr)
721e846c7aSMarc Kleine-Budde {
731e846c7aSMarc Kleine-Budde struct net_device_stats *stats = &priv->ndev->stats;
74759822a3SMarc Kleine-Budde u32 seq, tef_tail_masked, tef_tail;
751e846c7aSMarc Kleine-Budde struct sk_buff *skb;
761e846c7aSMarc Kleine-Budde
771e846c7aSMarc Kleine-Budde /* Use the MCP2517FD mask on the MCP2518FD, too. We only
78759822a3SMarc Kleine-Budde * compare 7 bits, this is enough to detect old TEF objects.
791e846c7aSMarc Kleine-Budde */
80759822a3SMarc Kleine-Budde seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK,
81759822a3SMarc Kleine-Budde hw_tef_obj->flags);
821e846c7aSMarc Kleine-Budde tef_tail_masked = priv->tef->tail &
831e846c7aSMarc Kleine-Budde field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
84759822a3SMarc Kleine-Budde
85759822a3SMarc Kleine-Budde /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
86759822a3SMarc Kleine-Budde * bits of a FIFOSTA register, here the TX FIFO tail index
87759822a3SMarc Kleine-Budde * might be corrupted and we might process past the TEF FIFO's
88759822a3SMarc Kleine-Budde * head into old CAN frames.
89759822a3SMarc Kleine-Budde *
90759822a3SMarc Kleine-Budde * Compare the sequence number of the currently processed CAN
91759822a3SMarc Kleine-Budde * frame with the expected sequence number. Abort with
92759822a3SMarc Kleine-Budde * -EBADMSG if an old CAN frame is detected.
93759822a3SMarc Kleine-Budde */
94759822a3SMarc Kleine-Budde if (seq != tef_tail_masked) {
95759822a3SMarc Kleine-Budde netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__,
96759822a3SMarc Kleine-Budde seq, tef_tail_masked);
97759822a3SMarc Kleine-Budde stats->tx_fifo_errors++;
98759822a3SMarc Kleine-Budde
99759822a3SMarc Kleine-Budde return -EBADMSG;
100759822a3SMarc Kleine-Budde }
1011e846c7aSMarc Kleine-Budde
1021e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv);
1031e846c7aSMarc Kleine-Budde skb = priv->can.echo_skb[tef_tail];
1041e846c7aSMarc Kleine-Budde if (skb)
1056cdc3fc4SMarc Kleine-Budde mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts);
1061e846c7aSMarc Kleine-Budde stats->tx_bytes +=
1072e3df4a3SMarc Kleine-Budde can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload,
1081e846c7aSMarc Kleine-Budde tef_tail, hw_tef_obj->ts,
1091e846c7aSMarc Kleine-Budde frame_len_ptr);
1101e846c7aSMarc Kleine-Budde stats->tx_packets++;
1111e846c7aSMarc Kleine-Budde priv->tef->tail++;
1121e846c7aSMarc Kleine-Budde
1131e846c7aSMarc Kleine-Budde return 0;
1141e846c7aSMarc Kleine-Budde }
1151e846c7aSMarc Kleine-Budde
1161333fd55SMarc Kleine-Budde static int
mcp251xfd_get_tef_len(struct mcp251xfd_priv * priv,u8 * len_p)1171333fd55SMarc Kleine-Budde mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p)
1181e846c7aSMarc Kleine-Budde {
1191e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
1201333fd55SMarc Kleine-Budde const u8 shift = tx_ring->obj_num_shift_to_u8;
1211333fd55SMarc Kleine-Budde u8 chip_tx_tail, tail, len;
1221333fd55SMarc Kleine-Budde u32 fifo_sta;
1231e846c7aSMarc Kleine-Budde int err;
1241e846c7aSMarc Kleine-Budde
1251333fd55SMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr),
1261333fd55SMarc Kleine-Budde &fifo_sta);
1271e846c7aSMarc Kleine-Budde if (err)
1281e846c7aSMarc Kleine-Budde return err;
1291e846c7aSMarc Kleine-Budde
13091017ba4SMarc Kleine-Budde /* If the chip says the TX-FIFO is empty, but there are no TX
13191017ba4SMarc Kleine-Budde * buffers free in the ring, we assume all have been sent.
13291017ba4SMarc Kleine-Budde */
13391017ba4SMarc Kleine-Budde if (mcp251xfd_tx_fifo_sta_empty(fifo_sta) &&
13491017ba4SMarc Kleine-Budde mcp251xfd_get_tx_free(tx_ring) == 0) {
1351333fd55SMarc Kleine-Budde *len_p = tx_ring->obj_num;
1361333fd55SMarc Kleine-Budde return 0;
1371333fd55SMarc Kleine-Budde }
1381333fd55SMarc Kleine-Budde
1391333fd55SMarc Kleine-Budde chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
1401333fd55SMarc Kleine-Budde
1411333fd55SMarc Kleine-Budde err = mcp251xfd_check_tef_tail(priv);
1421333fd55SMarc Kleine-Budde if (err)
1431333fd55SMarc Kleine-Budde return err;
1441333fd55SMarc Kleine-Budde tail = mcp251xfd_get_tef_tail(priv);
1451333fd55SMarc Kleine-Budde
1461333fd55SMarc Kleine-Budde /* First shift to full u8. The subtraction works on signed
1471333fd55SMarc Kleine-Budde * values, that keeps the difference steady around the u8
1481333fd55SMarc Kleine-Budde * overflow. The right shift acts on len, which is an u8.
1491e846c7aSMarc Kleine-Budde */
1501333fd55SMarc Kleine-Budde BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail));
1511333fd55SMarc Kleine-Budde BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail));
1521333fd55SMarc Kleine-Budde BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len));
1531e846c7aSMarc Kleine-Budde
1541333fd55SMarc Kleine-Budde len = (chip_tx_tail << shift) - (tail << shift);
155*50d66c86SMarc Kleine-Budde len >>= shift;
156*50d66c86SMarc Kleine-Budde
157*50d66c86SMarc Kleine-Budde /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
158*50d66c86SMarc Kleine-Budde * bits of a FIFOSTA register, here the TX-FIFO tail index
159*50d66c86SMarc Kleine-Budde * might be corrupted.
160*50d66c86SMarc Kleine-Budde *
161*50d66c86SMarc Kleine-Budde * However here it seems the bit indicating that the TX-FIFO
162*50d66c86SMarc Kleine-Budde * is empty (MCP251XFD_REG_FIFOSTA_TFERFFIF) is not correct
163*50d66c86SMarc Kleine-Budde * while the TX-FIFO tail index is.
164*50d66c86SMarc Kleine-Budde *
165*50d66c86SMarc Kleine-Budde * We assume the TX-FIFO is empty, i.e. all pending CAN frames
166*50d66c86SMarc Kleine-Budde * haven been send, if:
167*50d66c86SMarc Kleine-Budde * - Chip's head and tail index are equal (len == 0).
168*50d66c86SMarc Kleine-Budde * - The TX-FIFO is less than half full.
169*50d66c86SMarc Kleine-Budde * (The TX-FIFO empty case has already been checked at the
170*50d66c86SMarc Kleine-Budde * beginning of this function.)
171*50d66c86SMarc Kleine-Budde * - No free buffers in the TX ring.
172*50d66c86SMarc Kleine-Budde */
173*50d66c86SMarc Kleine-Budde if (len == 0 && mcp251xfd_tx_fifo_sta_less_than_half_full(fifo_sta) &&
174*50d66c86SMarc Kleine-Budde mcp251xfd_get_tx_free(tx_ring) == 0)
175*50d66c86SMarc Kleine-Budde len = tx_ring->obj_num;
176*50d66c86SMarc Kleine-Budde
177*50d66c86SMarc Kleine-Budde *len_p = len;
1781e846c7aSMarc Kleine-Budde
1791333fd55SMarc Kleine-Budde return 0;
1801e846c7aSMarc Kleine-Budde }
1811e846c7aSMarc Kleine-Budde
1821e846c7aSMarc Kleine-Budde static inline int
mcp251xfd_tef_obj_read(const struct mcp251xfd_priv * priv,struct mcp251xfd_hw_tef_obj * hw_tef_obj,const u8 offset,const u8 len)1831e846c7aSMarc Kleine-Budde mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
1841e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj *hw_tef_obj,
1851e846c7aSMarc Kleine-Budde const u8 offset, const u8 len)
1861e846c7aSMarc Kleine-Budde {
1871e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
1881e846c7aSMarc Kleine-Budde const int val_bytes = regmap_get_val_bytes(priv->map_rx);
1891e846c7aSMarc Kleine-Budde
1901e846c7aSMarc Kleine-Budde if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
1911e846c7aSMarc Kleine-Budde (offset > tx_ring->obj_num ||
1921e846c7aSMarc Kleine-Budde len > tx_ring->obj_num ||
1931e846c7aSMarc Kleine-Budde offset + len > tx_ring->obj_num)) {
1941e846c7aSMarc Kleine-Budde netdev_err(priv->ndev,
1951e846c7aSMarc Kleine-Budde "Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n",
1961e846c7aSMarc Kleine-Budde tx_ring->obj_num, offset, len);
1971e846c7aSMarc Kleine-Budde return -ERANGE;
1981e846c7aSMarc Kleine-Budde }
1991e846c7aSMarc Kleine-Budde
2001e846c7aSMarc Kleine-Budde return regmap_bulk_read(priv->map_rx,
2011e846c7aSMarc Kleine-Budde mcp251xfd_get_tef_obj_addr(offset),
2021e846c7aSMarc Kleine-Budde hw_tef_obj,
2031e846c7aSMarc Kleine-Budde sizeof(*hw_tef_obj) / val_bytes * len);
2041e846c7aSMarc Kleine-Budde }
2051e846c7aSMarc Kleine-Budde
mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv * priv)2061e846c7aSMarc Kleine-Budde static inline void mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv *priv)
2071e846c7aSMarc Kleine-Budde {
2081e846c7aSMarc Kleine-Budde struct mcp251xfd_ecc *ecc = &priv->ecc;
2091e846c7aSMarc Kleine-Budde
2101e846c7aSMarc Kleine-Budde ecc->ecc_stat = 0;
2111e846c7aSMarc Kleine-Budde }
2121e846c7aSMarc Kleine-Budde
mcp251xfd_handle_tefif(struct mcp251xfd_priv * priv)2131e846c7aSMarc Kleine-Budde int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
2141e846c7aSMarc Kleine-Budde {
2151e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
2161e846c7aSMarc Kleine-Budde unsigned int total_frame_len = 0;
2171e846c7aSMarc Kleine-Budde u8 tef_tail, len, l;
2181e846c7aSMarc Kleine-Budde int err, i;
2191e846c7aSMarc Kleine-Budde
2201333fd55SMarc Kleine-Budde err = mcp251xfd_get_tef_len(priv, &len);
2211e846c7aSMarc Kleine-Budde if (err)
2221e846c7aSMarc Kleine-Budde return err;
2231e846c7aSMarc Kleine-Budde
2241e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv);
2251333fd55SMarc Kleine-Budde l = mcp251xfd_get_tef_linear_len(priv, len);
2261e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l);
2271e846c7aSMarc Kleine-Budde if (err)
2281e846c7aSMarc Kleine-Budde return err;
2291e846c7aSMarc Kleine-Budde
2301e846c7aSMarc Kleine-Budde if (l < len) {
2311e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, &hw_tef_obj[l], 0, len - l);
2321e846c7aSMarc Kleine-Budde if (err)
2331e846c7aSMarc Kleine-Budde return err;
2341e846c7aSMarc Kleine-Budde }
2351e846c7aSMarc Kleine-Budde
2361e846c7aSMarc Kleine-Budde for (i = 0; i < len; i++) {
2371e846c7aSMarc Kleine-Budde unsigned int frame_len = 0;
2381e846c7aSMarc Kleine-Budde
2391e846c7aSMarc Kleine-Budde err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
240759822a3SMarc Kleine-Budde /* -EBADMSG means we're affected by mcp2518fd erratum
241759822a3SMarc Kleine-Budde * DS80000789E 6., i.e. the Sequence Number in the TEF
242759822a3SMarc Kleine-Budde * doesn't match our tef_tail. Don't process any
243759822a3SMarc Kleine-Budde * further and mark processed frames as good.
2441e846c7aSMarc Kleine-Budde */
245759822a3SMarc Kleine-Budde if (err == -EBADMSG)
2461e846c7aSMarc Kleine-Budde goto out_netif_wake_queue;
2471e846c7aSMarc Kleine-Budde if (err)
2481e846c7aSMarc Kleine-Budde return err;
2491e846c7aSMarc Kleine-Budde
2501e846c7aSMarc Kleine-Budde total_frame_len += frame_len;
2511e846c7aSMarc Kleine-Budde }
2521e846c7aSMarc Kleine-Budde
2531e846c7aSMarc Kleine-Budde out_netif_wake_queue:
2541e846c7aSMarc Kleine-Budde len = i; /* number of handled goods TEFs */
2551e846c7aSMarc Kleine-Budde if (len) {
2561e846c7aSMarc Kleine-Budde struct mcp251xfd_tef_ring *ring = priv->tef;
2571e846c7aSMarc Kleine-Budde struct mcp251xfd_tx_ring *tx_ring = priv->tx;
2581e846c7aSMarc Kleine-Budde int offset;
2591e846c7aSMarc Kleine-Budde
2601333fd55SMarc Kleine-Budde ring->head += len;
2611333fd55SMarc Kleine-Budde
2621e846c7aSMarc Kleine-Budde /* Increment the TEF FIFO tail pointer 'len' times in
2631e846c7aSMarc Kleine-Budde * a single SPI message.
2641e846c7aSMarc Kleine-Budde *
2651e846c7aSMarc Kleine-Budde * Note:
2661e846c7aSMarc Kleine-Budde * Calculate offset, so that the SPI transfer ends on
2671e846c7aSMarc Kleine-Budde * the last message of the uinc_xfer array, which has
2681e846c7aSMarc Kleine-Budde * "cs_change == 0", to properly deactivate the chip
2691e846c7aSMarc Kleine-Budde * select.
2701e846c7aSMarc Kleine-Budde */
2711e846c7aSMarc Kleine-Budde offset = ARRAY_SIZE(ring->uinc_xfer) - len;
2721e846c7aSMarc Kleine-Budde err = spi_sync_transfer(priv->spi,
2731e846c7aSMarc Kleine-Budde ring->uinc_xfer + offset, len);
2741e846c7aSMarc Kleine-Budde if (err)
2751e846c7aSMarc Kleine-Budde return err;
2761e846c7aSMarc Kleine-Budde
2771e846c7aSMarc Kleine-Budde tx_ring->tail += len;
2781e846c7aSMarc Kleine-Budde netdev_completed_queue(priv->ndev, len, total_frame_len);
2791e846c7aSMarc Kleine-Budde
2801e846c7aSMarc Kleine-Budde err = mcp251xfd_check_tef_tail(priv);
2811e846c7aSMarc Kleine-Budde if (err)
2821e846c7aSMarc Kleine-Budde return err;
2831e846c7aSMarc Kleine-Budde }
2841e846c7aSMarc Kleine-Budde
2851e846c7aSMarc Kleine-Budde mcp251xfd_ecc_tefif_successful(priv);
2861e846c7aSMarc Kleine-Budde
2871e846c7aSMarc Kleine-Budde if (mcp251xfd_get_tx_free(priv->tx)) {
2881e846c7aSMarc Kleine-Budde /* Make sure that anybody stopping the queue after
2891e846c7aSMarc Kleine-Budde * this sees the new tx_ring->tail.
2901e846c7aSMarc Kleine-Budde */
2911e846c7aSMarc Kleine-Budde smp_mb();
2921e846c7aSMarc Kleine-Budde netif_wake_queue(priv->ndev);
2931e846c7aSMarc Kleine-Budde }
2941e846c7aSMarc Kleine-Budde
295169d00a2SMarc Kleine-Budde if (priv->tx_coalesce_usecs_irq)
296169d00a2SMarc Kleine-Budde hrtimer_start(&priv->tx_irq_timer,
297169d00a2SMarc Kleine-Budde ns_to_ktime(priv->tx_coalesce_usecs_irq *
298169d00a2SMarc Kleine-Budde NSEC_PER_USEC),
299169d00a2SMarc Kleine-Budde HRTIMER_MODE_REL);
300169d00a2SMarc Kleine-Budde
3011e846c7aSMarc Kleine-Budde return 0;
3021e846c7aSMarc Kleine-Budde }
303