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 // 51e846c7aSMarc Kleine-Budde // Copyright (c) 2019, 2020, 2021 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 191e846c7aSMarc Kleine-Budde static inline int 201e846c7aSMarc Kleine-Budde mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, 211e846c7aSMarc Kleine-Budde u8 *tef_tail) 221e846c7aSMarc Kleine-Budde { 231e846c7aSMarc Kleine-Budde u32 tef_ua; 241e846c7aSMarc Kleine-Budde int err; 251e846c7aSMarc Kleine-Budde 261e846c7aSMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFUA, &tef_ua); 271e846c7aSMarc Kleine-Budde if (err) 281e846c7aSMarc Kleine-Budde return err; 291e846c7aSMarc Kleine-Budde 301e846c7aSMarc Kleine-Budde *tef_tail = tef_ua / sizeof(struct mcp251xfd_hw_tef_obj); 311e846c7aSMarc Kleine-Budde 321e846c7aSMarc Kleine-Budde return 0; 331e846c7aSMarc Kleine-Budde } 341e846c7aSMarc Kleine-Budde 351e846c7aSMarc Kleine-Budde static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv) 361e846c7aSMarc Kleine-Budde { 371e846c7aSMarc Kleine-Budde u8 tef_tail_chip, tef_tail; 381e846c7aSMarc Kleine-Budde int err; 391e846c7aSMarc Kleine-Budde 401e846c7aSMarc Kleine-Budde if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY)) 411e846c7aSMarc Kleine-Budde return 0; 421e846c7aSMarc Kleine-Budde 431e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_tail_get_from_chip(priv, &tef_tail_chip); 441e846c7aSMarc Kleine-Budde if (err) 451e846c7aSMarc Kleine-Budde return err; 461e846c7aSMarc Kleine-Budde 471e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 481e846c7aSMarc Kleine-Budde if (tef_tail_chip != tef_tail) { 491e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 501e846c7aSMarc Kleine-Budde "TEF tail of chip (0x%02x) and ours (0x%08x) inconsistent.\n", 511e846c7aSMarc Kleine-Budde tef_tail_chip, tef_tail); 521e846c7aSMarc Kleine-Budde return -EILSEQ; 531e846c7aSMarc Kleine-Budde } 541e846c7aSMarc Kleine-Budde 551e846c7aSMarc Kleine-Budde return 0; 561e846c7aSMarc Kleine-Budde } 571e846c7aSMarc Kleine-Budde 581e846c7aSMarc Kleine-Budde static int 591e846c7aSMarc Kleine-Budde mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) 601e846c7aSMarc Kleine-Budde { 611e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 621e846c7aSMarc Kleine-Budde u32 tef_sta; 631e846c7aSMarc Kleine-Budde int err; 641e846c7aSMarc Kleine-Budde 651e846c7aSMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); 661e846c7aSMarc Kleine-Budde if (err) 671e846c7aSMarc Kleine-Budde return err; 681e846c7aSMarc Kleine-Budde 691e846c7aSMarc Kleine-Budde if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { 701e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 711e846c7aSMarc Kleine-Budde "Transmit Event FIFO buffer overflow.\n"); 721e846c7aSMarc Kleine-Budde return -ENOBUFS; 731e846c7aSMarc Kleine-Budde } 741e846c7aSMarc Kleine-Budde 751e846c7aSMarc Kleine-Budde netdev_info(priv->ndev, 761e846c7aSMarc Kleine-Budde "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", 771e846c7aSMarc Kleine-Budde tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? 781e846c7aSMarc Kleine-Budde "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? 791e846c7aSMarc Kleine-Budde "not empty" : "empty", 801e846c7aSMarc Kleine-Budde seq, priv->tef->tail, priv->tef->head, tx_ring->head); 811e846c7aSMarc Kleine-Budde 821e846c7aSMarc Kleine-Budde /* The Sequence Number in the TEF doesn't match our tef_tail. */ 831e846c7aSMarc Kleine-Budde return -EAGAIN; 841e846c7aSMarc Kleine-Budde } 851e846c7aSMarc Kleine-Budde 861e846c7aSMarc Kleine-Budde static int 871e846c7aSMarc Kleine-Budde mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, 881e846c7aSMarc Kleine-Budde const struct mcp251xfd_hw_tef_obj *hw_tef_obj, 891e846c7aSMarc Kleine-Budde unsigned int *frame_len_ptr) 901e846c7aSMarc Kleine-Budde { 911e846c7aSMarc Kleine-Budde struct net_device_stats *stats = &priv->ndev->stats; 921e846c7aSMarc Kleine-Budde struct sk_buff *skb; 931e846c7aSMarc Kleine-Budde u32 seq, seq_masked, tef_tail_masked, tef_tail; 941e846c7aSMarc Kleine-Budde 951e846c7aSMarc Kleine-Budde seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, 961e846c7aSMarc Kleine-Budde hw_tef_obj->flags); 971e846c7aSMarc Kleine-Budde 981e846c7aSMarc Kleine-Budde /* Use the MCP2517FD mask on the MCP2518FD, too. We only 991e846c7aSMarc Kleine-Budde * compare 7 bits, this should be enough to detect 1001e846c7aSMarc Kleine-Budde * net-yet-completed, i.e. old TEF objects. 1011e846c7aSMarc Kleine-Budde */ 1021e846c7aSMarc Kleine-Budde seq_masked = seq & 1031e846c7aSMarc Kleine-Budde field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 1041e846c7aSMarc Kleine-Budde tef_tail_masked = priv->tef->tail & 1051e846c7aSMarc Kleine-Budde field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 1061e846c7aSMarc Kleine-Budde if (seq_masked != tef_tail_masked) 1071e846c7aSMarc Kleine-Budde return mcp251xfd_handle_tefif_recover(priv, seq); 1081e846c7aSMarc Kleine-Budde 1091e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 1101e846c7aSMarc Kleine-Budde skb = priv->can.echo_skb[tef_tail]; 1111e846c7aSMarc Kleine-Budde if (skb) 1121e846c7aSMarc Kleine-Budde mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts); 1131e846c7aSMarc Kleine-Budde stats->tx_bytes += 1141e846c7aSMarc Kleine-Budde can_rx_offload_get_echo_skb(&priv->offload, 1151e846c7aSMarc Kleine-Budde tef_tail, hw_tef_obj->ts, 1161e846c7aSMarc Kleine-Budde frame_len_ptr); 1171e846c7aSMarc Kleine-Budde stats->tx_packets++; 1181e846c7aSMarc Kleine-Budde priv->tef->tail++; 1191e846c7aSMarc Kleine-Budde 1201e846c7aSMarc Kleine-Budde return 0; 1211e846c7aSMarc Kleine-Budde } 1221e846c7aSMarc Kleine-Budde 1231e846c7aSMarc Kleine-Budde static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) 1241e846c7aSMarc Kleine-Budde { 1251e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 1261e846c7aSMarc Kleine-Budde unsigned int new_head; 1271e846c7aSMarc Kleine-Budde u8 chip_tx_tail; 1281e846c7aSMarc Kleine-Budde int err; 1291e846c7aSMarc Kleine-Budde 1301e846c7aSMarc Kleine-Budde err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); 1311e846c7aSMarc Kleine-Budde if (err) 1321e846c7aSMarc Kleine-Budde return err; 1331e846c7aSMarc Kleine-Budde 1341e846c7aSMarc Kleine-Budde /* chip_tx_tail, is the next TX-Object send by the HW. 1351e846c7aSMarc Kleine-Budde * The new TEF head must be >= the old head, ... 1361e846c7aSMarc Kleine-Budde */ 1371e846c7aSMarc Kleine-Budde new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; 1381e846c7aSMarc Kleine-Budde if (new_head <= priv->tef->head) 1391e846c7aSMarc Kleine-Budde new_head += tx_ring->obj_num; 1401e846c7aSMarc Kleine-Budde 1411e846c7aSMarc Kleine-Budde /* ... but it cannot exceed the TX head. */ 1421e846c7aSMarc Kleine-Budde priv->tef->head = min(new_head, tx_ring->head); 1431e846c7aSMarc Kleine-Budde 1441e846c7aSMarc Kleine-Budde return mcp251xfd_check_tef_tail(priv); 1451e846c7aSMarc Kleine-Budde } 1461e846c7aSMarc Kleine-Budde 1471e846c7aSMarc Kleine-Budde static inline int 1481e846c7aSMarc Kleine-Budde mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, 1491e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj *hw_tef_obj, 1501e846c7aSMarc Kleine-Budde const u8 offset, const u8 len) 1511e846c7aSMarc Kleine-Budde { 1521e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 1531e846c7aSMarc Kleine-Budde const int val_bytes = regmap_get_val_bytes(priv->map_rx); 1541e846c7aSMarc Kleine-Budde 1551e846c7aSMarc Kleine-Budde if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) && 1561e846c7aSMarc Kleine-Budde (offset > tx_ring->obj_num || 1571e846c7aSMarc Kleine-Budde len > tx_ring->obj_num || 1581e846c7aSMarc Kleine-Budde offset + len > tx_ring->obj_num)) { 1591e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 1601e846c7aSMarc Kleine-Budde "Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n", 1611e846c7aSMarc Kleine-Budde tx_ring->obj_num, offset, len); 1621e846c7aSMarc Kleine-Budde return -ERANGE; 1631e846c7aSMarc Kleine-Budde } 1641e846c7aSMarc Kleine-Budde 1651e846c7aSMarc Kleine-Budde return regmap_bulk_read(priv->map_rx, 1661e846c7aSMarc Kleine-Budde mcp251xfd_get_tef_obj_addr(offset), 1671e846c7aSMarc Kleine-Budde hw_tef_obj, 1681e846c7aSMarc Kleine-Budde sizeof(*hw_tef_obj) / val_bytes * len); 1691e846c7aSMarc Kleine-Budde } 1701e846c7aSMarc Kleine-Budde 1711e846c7aSMarc Kleine-Budde static inline void mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv *priv) 1721e846c7aSMarc Kleine-Budde { 1731e846c7aSMarc Kleine-Budde struct mcp251xfd_ecc *ecc = &priv->ecc; 1741e846c7aSMarc Kleine-Budde 1751e846c7aSMarc Kleine-Budde ecc->ecc_stat = 0; 1761e846c7aSMarc Kleine-Budde } 1771e846c7aSMarc Kleine-Budde 1781e846c7aSMarc Kleine-Budde int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) 1791e846c7aSMarc Kleine-Budde { 1801e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX]; 1811e846c7aSMarc Kleine-Budde unsigned int total_frame_len = 0; 1821e846c7aSMarc Kleine-Budde u8 tef_tail, len, l; 1831e846c7aSMarc Kleine-Budde int err, i; 1841e846c7aSMarc Kleine-Budde 1851e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_ring_update(priv); 1861e846c7aSMarc Kleine-Budde if (err) 1871e846c7aSMarc Kleine-Budde return err; 1881e846c7aSMarc Kleine-Budde 1891e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 1901e846c7aSMarc Kleine-Budde len = mcp251xfd_get_tef_len(priv); 1911e846c7aSMarc Kleine-Budde l = mcp251xfd_get_tef_linear_len(priv); 1921e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); 1931e846c7aSMarc Kleine-Budde if (err) 1941e846c7aSMarc Kleine-Budde return err; 1951e846c7aSMarc Kleine-Budde 1961e846c7aSMarc Kleine-Budde if (l < len) { 1971e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, &hw_tef_obj[l], 0, len - l); 1981e846c7aSMarc Kleine-Budde if (err) 1991e846c7aSMarc Kleine-Budde return err; 2001e846c7aSMarc Kleine-Budde } 2011e846c7aSMarc Kleine-Budde 2021e846c7aSMarc Kleine-Budde for (i = 0; i < len; i++) { 2031e846c7aSMarc Kleine-Budde unsigned int frame_len = 0; 2041e846c7aSMarc Kleine-Budde 2051e846c7aSMarc Kleine-Budde err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); 2061e846c7aSMarc Kleine-Budde /* -EAGAIN means the Sequence Number in the TEF 2071e846c7aSMarc Kleine-Budde * doesn't match our tef_tail. This can happen if we 2081e846c7aSMarc Kleine-Budde * read the TEF objects too early. Leave loop let the 2091e846c7aSMarc Kleine-Budde * interrupt handler call us again. 2101e846c7aSMarc Kleine-Budde */ 2111e846c7aSMarc Kleine-Budde if (err == -EAGAIN) 2121e846c7aSMarc Kleine-Budde goto out_netif_wake_queue; 2131e846c7aSMarc Kleine-Budde if (err) 2141e846c7aSMarc Kleine-Budde return err; 2151e846c7aSMarc Kleine-Budde 2161e846c7aSMarc Kleine-Budde total_frame_len += frame_len; 2171e846c7aSMarc Kleine-Budde } 2181e846c7aSMarc Kleine-Budde 2191e846c7aSMarc Kleine-Budde out_netif_wake_queue: 2201e846c7aSMarc Kleine-Budde len = i; /* number of handled goods TEFs */ 2211e846c7aSMarc Kleine-Budde if (len) { 2221e846c7aSMarc Kleine-Budde struct mcp251xfd_tef_ring *ring = priv->tef; 2231e846c7aSMarc Kleine-Budde struct mcp251xfd_tx_ring *tx_ring = priv->tx; 2241e846c7aSMarc Kleine-Budde int offset; 2251e846c7aSMarc Kleine-Budde 2261e846c7aSMarc Kleine-Budde /* Increment the TEF FIFO tail pointer 'len' times in 2271e846c7aSMarc Kleine-Budde * a single SPI message. 2281e846c7aSMarc Kleine-Budde * 2291e846c7aSMarc Kleine-Budde * Note: 2301e846c7aSMarc Kleine-Budde * Calculate offset, so that the SPI transfer ends on 2311e846c7aSMarc Kleine-Budde * the last message of the uinc_xfer array, which has 2321e846c7aSMarc Kleine-Budde * "cs_change == 0", to properly deactivate the chip 2331e846c7aSMarc Kleine-Budde * select. 2341e846c7aSMarc Kleine-Budde */ 2351e846c7aSMarc Kleine-Budde offset = ARRAY_SIZE(ring->uinc_xfer) - len; 2361e846c7aSMarc Kleine-Budde err = spi_sync_transfer(priv->spi, 2371e846c7aSMarc Kleine-Budde ring->uinc_xfer + offset, len); 2381e846c7aSMarc Kleine-Budde if (err) 2391e846c7aSMarc Kleine-Budde return err; 2401e846c7aSMarc Kleine-Budde 2411e846c7aSMarc Kleine-Budde tx_ring->tail += len; 2421e846c7aSMarc Kleine-Budde netdev_completed_queue(priv->ndev, len, total_frame_len); 2431e846c7aSMarc Kleine-Budde 2441e846c7aSMarc Kleine-Budde err = mcp251xfd_check_tef_tail(priv); 2451e846c7aSMarc Kleine-Budde if (err) 2461e846c7aSMarc Kleine-Budde return err; 2471e846c7aSMarc Kleine-Budde } 2481e846c7aSMarc Kleine-Budde 2491e846c7aSMarc Kleine-Budde mcp251xfd_ecc_tefif_successful(priv); 2501e846c7aSMarc Kleine-Budde 2511e846c7aSMarc Kleine-Budde if (mcp251xfd_get_tx_free(priv->tx)) { 2521e846c7aSMarc Kleine-Budde /* Make sure that anybody stopping the queue after 2531e846c7aSMarc Kleine-Budde * this sees the new tx_ring->tail. 2541e846c7aSMarc Kleine-Budde */ 2551e846c7aSMarc Kleine-Budde smp_mb(); 2561e846c7aSMarc Kleine-Budde netif_wake_queue(priv->ndev); 2571e846c7aSMarc Kleine-Budde } 2581e846c7aSMarc Kleine-Budde 259*169d00a2SMarc Kleine-Budde if (priv->tx_coalesce_usecs_irq) 260*169d00a2SMarc Kleine-Budde hrtimer_start(&priv->tx_irq_timer, 261*169d00a2SMarc Kleine-Budde ns_to_ktime(priv->tx_coalesce_usecs_irq * 262*169d00a2SMarc Kleine-Budde NSEC_PER_USEC), 263*169d00a2SMarc Kleine-Budde HRTIMER_MODE_REL); 264*169d00a2SMarc Kleine-Budde 2651e846c7aSMarc Kleine-Budde return 0; 2661e846c7aSMarc Kleine-Budde } 267