Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
0004 //
0005 // Copyright (c) 2019, 2020, 2021 Pengutronix,
0006 //               Marc Kleine-Budde <kernel@pengutronix.de>
0007 //
0008 // Based on:
0009 //
0010 // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
0011 //
0012 // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
0013 //
0014 
0015 #include <linux/bitfield.h>
0016 
0017 #include "mcp251xfd.h"
0018 
0019 static inline int
0020 mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv,
0021                  u8 *tef_tail)
0022 {
0023     u32 tef_ua;
0024     int err;
0025 
0026     err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFUA, &tef_ua);
0027     if (err)
0028         return err;
0029 
0030     *tef_tail = tef_ua / sizeof(struct mcp251xfd_hw_tef_obj);
0031 
0032     return 0;
0033 }
0034 
0035 static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv)
0036 {
0037     u8 tef_tail_chip, tef_tail;
0038     int err;
0039 
0040     if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY))
0041         return 0;
0042 
0043     err = mcp251xfd_tef_tail_get_from_chip(priv, &tef_tail_chip);
0044     if (err)
0045         return err;
0046 
0047     tef_tail = mcp251xfd_get_tef_tail(priv);
0048     if (tef_tail_chip != tef_tail) {
0049         netdev_err(priv->ndev,
0050                "TEF tail of chip (0x%02x) and ours (0x%08x) inconsistent.\n",
0051                tef_tail_chip, tef_tail);
0052         return -EILSEQ;
0053     }
0054 
0055     return 0;
0056 }
0057 
0058 static int
0059 mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
0060 {
0061     const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
0062     u32 tef_sta;
0063     int err;
0064 
0065     err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta);
0066     if (err)
0067         return err;
0068 
0069     if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) {
0070         netdev_err(priv->ndev,
0071                "Transmit Event FIFO buffer overflow.\n");
0072         return -ENOBUFS;
0073     }
0074 
0075     netdev_info(priv->ndev,
0076             "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n",
0077             tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ?
0078             "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ?
0079             "not empty" : "empty",
0080             seq, priv->tef->tail, priv->tef->head, tx_ring->head);
0081 
0082     /* The Sequence Number in the TEF doesn't match our tef_tail. */
0083     return -EAGAIN;
0084 }
0085 
0086 static int
0087 mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
0088                const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
0089                unsigned int *frame_len_ptr)
0090 {
0091     struct net_device_stats *stats = &priv->ndev->stats;
0092     struct sk_buff *skb;
0093     u32 seq, seq_masked, tef_tail_masked, tef_tail;
0094 
0095     seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK,
0096             hw_tef_obj->flags);
0097 
0098     /* Use the MCP2517FD mask on the MCP2518FD, too. We only
0099      * compare 7 bits, this should be enough to detect
0100      * net-yet-completed, i.e. old TEF objects.
0101      */
0102     seq_masked = seq &
0103         field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
0104     tef_tail_masked = priv->tef->tail &
0105         field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
0106     if (seq_masked != tef_tail_masked)
0107         return mcp251xfd_handle_tefif_recover(priv, seq);
0108 
0109     tef_tail = mcp251xfd_get_tef_tail(priv);
0110     skb = priv->can.echo_skb[tef_tail];
0111     if (skb)
0112         mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts);
0113     stats->tx_bytes +=
0114         can_rx_offload_get_echo_skb(&priv->offload,
0115                         tef_tail, hw_tef_obj->ts,
0116                         frame_len_ptr);
0117     stats->tx_packets++;
0118     priv->tef->tail++;
0119 
0120     return 0;
0121 }
0122 
0123 static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv)
0124 {
0125     const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
0126     unsigned int new_head;
0127     u8 chip_tx_tail;
0128     int err;
0129 
0130     err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail);
0131     if (err)
0132         return err;
0133 
0134     /* chip_tx_tail, is the next TX-Object send by the HW.
0135      * The new TEF head must be >= the old head, ...
0136      */
0137     new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail;
0138     if (new_head <= priv->tef->head)
0139         new_head += tx_ring->obj_num;
0140 
0141     /* ... but it cannot exceed the TX head. */
0142     priv->tef->head = min(new_head, tx_ring->head);
0143 
0144     return mcp251xfd_check_tef_tail(priv);
0145 }
0146 
0147 static inline int
0148 mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
0149                struct mcp251xfd_hw_tef_obj *hw_tef_obj,
0150                const u8 offset, const u8 len)
0151 {
0152     const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
0153     const int val_bytes = regmap_get_val_bytes(priv->map_rx);
0154 
0155     if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
0156         (offset > tx_ring->obj_num ||
0157          len > tx_ring->obj_num ||
0158          offset + len > tx_ring->obj_num)) {
0159         netdev_err(priv->ndev,
0160                "Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n",
0161                tx_ring->obj_num, offset, len);
0162         return -ERANGE;
0163     }
0164 
0165     return regmap_bulk_read(priv->map_rx,
0166                 mcp251xfd_get_tef_obj_addr(offset),
0167                 hw_tef_obj,
0168                 sizeof(*hw_tef_obj) / val_bytes * len);
0169 }
0170 
0171 static inline void mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv *priv)
0172 {
0173     struct mcp251xfd_ecc *ecc = &priv->ecc;
0174 
0175     ecc->ecc_stat = 0;
0176 }
0177 
0178 int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
0179 {
0180     struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
0181     unsigned int total_frame_len = 0;
0182     u8 tef_tail, len, l;
0183     int err, i;
0184 
0185     err = mcp251xfd_tef_ring_update(priv);
0186     if (err)
0187         return err;
0188 
0189     tef_tail = mcp251xfd_get_tef_tail(priv);
0190     len = mcp251xfd_get_tef_len(priv);
0191     l = mcp251xfd_get_tef_linear_len(priv);
0192     err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l);
0193     if (err)
0194         return err;
0195 
0196     if (l < len) {
0197         err = mcp251xfd_tef_obj_read(priv, &hw_tef_obj[l], 0, len - l);
0198         if (err)
0199             return err;
0200     }
0201 
0202     for (i = 0; i < len; i++) {
0203         unsigned int frame_len = 0;
0204 
0205         err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
0206         /* -EAGAIN means the Sequence Number in the TEF
0207          * doesn't match our tef_tail. This can happen if we
0208          * read the TEF objects too early. Leave loop let the
0209          * interrupt handler call us again.
0210          */
0211         if (err == -EAGAIN)
0212             goto out_netif_wake_queue;
0213         if (err)
0214             return err;
0215 
0216         total_frame_len += frame_len;
0217     }
0218 
0219  out_netif_wake_queue:
0220     len = i;    /* number of handled goods TEFs */
0221     if (len) {
0222         struct mcp251xfd_tef_ring *ring = priv->tef;
0223         struct mcp251xfd_tx_ring *tx_ring = priv->tx;
0224         int offset;
0225 
0226         /* Increment the TEF FIFO tail pointer 'len' times in
0227          * a single SPI message.
0228          *
0229          * Note:
0230          * Calculate offset, so that the SPI transfer ends on
0231          * the last message of the uinc_xfer array, which has
0232          * "cs_change == 0", to properly deactivate the chip
0233          * select.
0234          */
0235         offset = ARRAY_SIZE(ring->uinc_xfer) - len;
0236         err = spi_sync_transfer(priv->spi,
0237                     ring->uinc_xfer + offset, len);
0238         if (err)
0239             return err;
0240 
0241         tx_ring->tail += len;
0242         netdev_completed_queue(priv->ndev, len, total_frame_len);
0243 
0244         err = mcp251xfd_check_tef_tail(priv);
0245         if (err)
0246             return err;
0247     }
0248 
0249     mcp251xfd_ecc_tefif_successful(priv);
0250 
0251     if (mcp251xfd_get_tx_free(priv->tx)) {
0252         /* Make sure that anybody stopping the queue after
0253          * this sees the new tx_ring->tail.
0254          */
0255         smp_mb();
0256         netif_wake_queue(priv->ndev);
0257     }
0258 
0259     if (priv->tx_coalesce_usecs_irq)
0260         hrtimer_start(&priv->tx_irq_timer,
0261                   ns_to_ktime(priv->tx_coalesce_usecs_irq *
0262                       NSEC_PER_USEC),
0263                   HRTIMER_MODE_REL);
0264 
0265     return 0;
0266 }