mcp251xfd-rx.c 6.4 KB

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