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