1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4 // 5 // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, 6 // Marc Kleine-Budde <kernel@pengutronix.de> 7 // 8 // Based on: 9 // 10 // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface 11 // 12 // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> 13 // 14 15 #include <linux/bitfield.h> 16 17 #include "mcp251xfd.h" 18 19 static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta) 20 { 21 return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); 22 } 23 24 static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta) 25 { 26 return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; 27 } 28 29 static inline int 30 mcp251xfd_rx_tail_get_from_chip(const struct mcp251xfd_priv *priv, 31 const struct mcp251xfd_rx_ring *ring, 32 u8 *rx_tail) 33 { 34 u32 fifo_ua; 35 int err; 36 37 err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOUA(ring->fifo_nr), 38 &fifo_ua); 39 if (err) 40 return err; 41 42 fifo_ua -= ring->base - MCP251XFD_RAM_START; 43 *rx_tail = fifo_ua / ring->obj_size; 44 45 return 0; 46 } 47 48 static int 49 mcp251xfd_check_rx_tail(const struct mcp251xfd_priv *priv, 50 const struct mcp251xfd_rx_ring *ring) 51 { 52 u8 rx_tail_chip, rx_tail; 53 int err; 54 55 if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY)) 56 return 0; 57 58 err = mcp251xfd_rx_tail_get_from_chip(priv, ring, &rx_tail_chip); 59 if (err) 60 return err; 61 62 rx_tail = mcp251xfd_get_rx_tail(ring); 63 if (rx_tail_chip != rx_tail) { 64 netdev_err(priv->ndev, 65 "RX tail of chip (%d) and ours (%d) inconsistent.\n", 66 rx_tail_chip, rx_tail); 67 return -EILSEQ; 68 } 69 70 return 0; 71 } 72 73 static int 74 mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv, 75 const struct mcp251xfd_rx_ring *ring, 76 u8 *len_p) 77 { 78 const u8 shift = ring->obj_num_shift_to_u8; 79 u8 chip_head, tail, len; 80 u32 fifo_sta; 81 int err; 82 83 err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), 84 &fifo_sta); 85 if (err) 86 return err; 87 88 if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) { 89 *len_p = 0; 90 return 0; 91 } 92 93 if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) { 94 *len_p = ring->obj_num; 95 return 0; 96 } 97 98 chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); 99 100 err = mcp251xfd_check_rx_tail(priv, ring); 101 if (err) 102 return err; 103 tail = mcp251xfd_get_rx_tail(ring); 104 105 /* First shift to full u8. The subtraction works on signed 106 * values, that keeps the difference steady around the u8 107 * overflow. The right shift acts on len, which is an u8. 108 */ 109 BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head)); 110 BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail)); 111 BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len)); 112 113 len = (chip_head << shift) - (tail << shift); 114 *len_p = len >> shift; 115 116 return 0; 117 } 118 119 static void 120 mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, 121 const struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj, 122 struct sk_buff *skb) 123 { 124 struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 125 u8 dlc; 126 127 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_IDE) { 128 u32 sid, eid; 129 130 eid = FIELD_GET(MCP251XFD_OBJ_ID_EID_MASK, hw_rx_obj->id); 131 sid = FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK, hw_rx_obj->id); 132 133 cfd->can_id = CAN_EFF_FLAG | 134 FIELD_PREP(MCP251XFD_REG_FRAME_EFF_EID_MASK, eid) | 135 FIELD_PREP(MCP251XFD_REG_FRAME_EFF_SID_MASK, sid); 136 } else { 137 cfd->can_id = FIELD_GET(MCP251XFD_OBJ_ID_SID_MASK, 138 hw_rx_obj->id); 139 } 140 141 dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC_MASK, hw_rx_obj->flags); 142 143 /* CANFD */ 144 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) { 145 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_ESI) 146 cfd->flags |= CANFD_ESI; 147 148 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_BRS) 149 cfd->flags |= CANFD_BRS; 150 151 cfd->len = can_fd_dlc2len(dlc); 152 } else { 153 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR) 154 cfd->can_id |= CAN_RTR_FLAG; 155 156 can_frame_set_cc_len((struct can_frame *)cfd, dlc, 157 priv->can.ctrlmode); 158 } 159 160 if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) 161 memcpy(cfd->data, hw_rx_obj->data, cfd->len); 162 163 mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts); 164 } 165 166 static int 167 mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, 168 struct mcp251xfd_rx_ring *ring, 169 const struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj) 170 { 171 struct net_device_stats *stats = &priv->ndev->stats; 172 struct sk_buff *skb; 173 struct canfd_frame *cfd; 174 int err; 175 176 if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) 177 skb = alloc_canfd_skb(priv->ndev, &cfd); 178 else 179 skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cfd); 180 181 if (!skb) { 182 stats->rx_dropped++; 183 return 0; 184 } 185 186 mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb); 187 err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts); 188 if (err) 189 stats->rx_fifo_errors++; 190 191 return 0; 192 } 193 194 static inline int 195 mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv, 196 const struct mcp251xfd_rx_ring *ring, 197 struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj, 198 const u8 offset, const u8 len) 199 { 200 const int val_bytes = regmap_get_val_bytes(priv->map_rx); 201 int err; 202 203 err = regmap_bulk_read(priv->map_rx, 204 mcp251xfd_get_rx_obj_addr(ring, offset), 205 hw_rx_obj, 206 len * ring->obj_size / val_bytes); 207 208 return err; 209 } 210 211 static int 212 mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv, 213 struct mcp251xfd_rx_ring *ring, 214 u8 len) 215 { 216 int offset; 217 int err; 218 219 if (!len) 220 return 0; 221 222 ring->head += len; 223 224 /* Increment the RX FIFO tail pointer 'len' times in a 225 * single SPI message. 226 * 227 * Note: 228 * Calculate offset, so that the SPI transfer ends on 229 * the last message of the uinc_xfer array, which has 230 * "cs_change == 0", to properly deactivate the chip 231 * select. 232 */ 233 offset = ARRAY_SIZE(ring->uinc_xfer) - len; 234 err = spi_sync_transfer(priv->spi, 235 ring->uinc_xfer + offset, len); 236 if (err) 237 return err; 238 239 ring->tail += len; 240 241 return 0; 242 } 243 244 static int 245 mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, 246 struct mcp251xfd_rx_ring *ring) 247 { 248 struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj; 249 u8 rx_tail, len, l; 250 int err, i; 251 252 err = mcp251xfd_get_rx_len(priv, ring, &len); 253 if (err) 254 return err; 255 256 while ((l = mcp251xfd_get_rx_linear_len(ring, len))) { 257 rx_tail = mcp251xfd_get_rx_tail(ring); 258 259 err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj, 260 rx_tail, l); 261 if (err) 262 return err; 263 264 for (i = 0; i < l; i++) { 265 err = mcp251xfd_handle_rxif_one(priv, ring, 266 (void *)hw_rx_obj + 267 i * ring->obj_size); 268 if (err) 269 return err; 270 } 271 272 err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l); 273 if (err) 274 return err; 275 276 len -= l; 277 } 278 279 return 0; 280 } 281 282 int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv) 283 { 284 struct mcp251xfd_rx_ring *ring; 285 int err, n; 286 287 mcp251xfd_for_each_rx_ring(priv, ring, n) { 288 /* - if RX IRQ coalescing is active always handle ring 0 289 * - only handle rings if RX IRQ is active 290 */ 291 if ((ring->nr > 0 || !priv->rx_obj_num_coalesce_irq) && 292 !(priv->regs_status.rxif & BIT(ring->fifo_nr))) 293 continue; 294 295 err = mcp251xfd_handle_rxif_ring(priv, ring); 296 if (err) 297 return err; 298 } 299 300 if (priv->rx_coalesce_usecs_irq) 301 hrtimer_start(&priv->rx_irq_timer, 302 ns_to_ktime(priv->rx_coalesce_usecs_irq * 303 NSEC_PER_USEC), 304 HRTIMER_MODE_REL); 305 306 return 0; 307 } 308