0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
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
0099
0100
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
0135
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
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
0207
0208
0209
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;
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
0227
0228
0229
0230
0231
0232
0233
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
0253
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 }