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