802-can-0006-can-rx-offload-Prepare-for-CAN-FD-support.patch 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. From 42abc4a8a97a87734c759c02c5ba255ed5124a2c Mon Sep 17 00:00:00 2001
  2. From: Joakim Zhang <[email protected]>
  3. Date: Fri, 12 Jul 2019 08:02:38 +0000
  4. Subject: [PATCH] can: rx-offload: Prepare for CAN FD support
  5. The skbs for classic CAN and CAN FD frames are allocated with seperate
  6. functions: alloc_can_skb() and alloc_canfd_skb().
  7. In order to support CAN FD frames via the rx-offload helper, the driver
  8. itself has to allocate the skb (depending whether it received a classic
  9. CAN or CAN FD frame), as the rx-offload helper cannot know which kind of
  10. CAN frame the driver has received.
  11. This patch moves the allocation of the skb into the struct
  12. can_rx_offload::mailbox_read callbacks of the the flexcan and ti_hecc
  13. driver and adjusts the rx-offload helper accordingly.
  14. Signed-off-by: Joakim Zhang <[email protected]>
  15. Signed-off-by: Marc Kleine-Budde <[email protected]>
  16. ---
  17. drivers/net/can/flexcan.c | 27 +++++++++++-----
  18. drivers/net/can/rx-offload.c | 70 ++++++++++--------------------------------
  19. include/linux/can/rx-offload.h | 6 ++--
  20. 3 files changed, 40 insertions(+), 63 deletions(-)
  21. --- a/drivers/net/can/flexcan.c
  22. +++ b/drivers/net/can/flexcan.c
  23. @@ -785,16 +785,23 @@ static inline struct flexcan_priv *rx_of
  24. return container_of(offload, struct flexcan_priv, offload);
  25. }
  26. -static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
  27. - struct can_frame *cf,
  28. - u32 *timestamp, unsigned int n)
  29. +static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
  30. + unsigned int n, u32 *timestamp,
  31. + bool drop)
  32. {
  33. struct flexcan_priv *priv = rx_offload_to_priv(offload);
  34. struct flexcan_regs __iomem *regs = priv->regs;
  35. struct flexcan_mb __iomem *mb;
  36. + struct sk_buff *skb;
  37. + struct can_frame *cf;
  38. u32 reg_ctrl, reg_id, reg_iflag1;
  39. int i;
  40. + if (unlikely(drop)) {
  41. + skb = ERR_PTR(-ENOBUFS);
  42. + goto mark_as_read;
  43. + }
  44. +
  45. mb = flexcan_get_mb(priv, n);
  46. if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  47. @@ -808,7 +815,7 @@ static unsigned int flexcan_mailbox_read
  48. code = reg_ctrl & FLEXCAN_MB_CODE_MASK;
  49. if ((code != FLEXCAN_MB_CODE_RX_FULL) &&
  50. (code != FLEXCAN_MB_CODE_RX_OVERRUN))
  51. - return 0;
  52. + return NULL;
  53. if (code == FLEXCAN_MB_CODE_RX_OVERRUN) {
  54. /* This MB was overrun, we lost data */
  55. @@ -818,11 +825,17 @@ static unsigned int flexcan_mailbox_read
  56. } else {
  57. reg_iflag1 = priv->read(&regs->iflag1);
  58. if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
  59. - return 0;
  60. + return NULL;
  61. reg_ctrl = priv->read(&mb->can_ctrl);
  62. }
  63. + skb = alloc_can_skb(offload->dev, &cf);
  64. + if (!skb) {
  65. + skb = ERR_PTR(-ENOMEM);
  66. + goto mark_as_read;
  67. + }
  68. +
  69. /* increase timstamp to full 32 bit */
  70. *timestamp = reg_ctrl << 16;
  71. @@ -841,7 +854,7 @@ static unsigned int flexcan_mailbox_read
  72. *(__be32 *)(cf->data + i) = data;
  73. }
  74. - /* mark as read */
  75. + mark_as_read:
  76. if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
  77. /* Clear IRQ */
  78. if (n < 32)
  79. @@ -858,7 +871,7 @@ static unsigned int flexcan_mailbox_read
  80. */
  81. priv->read(&regs->timer);
  82. - return 1;
  83. + return skb;
  84. }
  85. --- a/drivers/net/can/rx-offload.c
  86. +++ b/drivers/net/can/rx-offload.c
  87. @@ -139,71 +139,35 @@ static int can_rx_offload_compare(struct
  88. static struct sk_buff *
  89. can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n)
  90. {
  91. - struct sk_buff *skb = NULL, *skb_error = NULL;
  92. + struct sk_buff *skb;
  93. struct can_rx_offload_cb *cb;
  94. - struct can_frame *cf;
  95. - int ret;
  96. + bool drop = false;
  97. + u32 timestamp;
  98. - if (likely(skb_queue_len(&offload->skb_queue) <
  99. - offload->skb_queue_len_max)) {
  100. - skb = alloc_can_skb(offload->dev, &cf);
  101. - if (unlikely(!skb))
  102. - skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */
  103. - } else {
  104. - skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */
  105. - }
  106. -
  107. - /* If queue is full or skb not available, drop by reading into
  108. - * overflow buffer.
  109. - */
  110. - if (unlikely(skb_error)) {
  111. - struct can_frame cf_overflow;
  112. - u32 timestamp;
  113. -
  114. - ret = offload->mailbox_read(offload, &cf_overflow,
  115. - &timestamp, n);
  116. -
  117. - /* Mailbox was empty. */
  118. - if (unlikely(!ret))
  119. - return NULL;
  120. -
  121. - /* Mailbox has been read and we're dropping it or
  122. - * there was a problem reading the mailbox.
  123. - *
  124. - * Increment error counters in any case.
  125. - */
  126. - offload->dev->stats.rx_dropped++;
  127. - offload->dev->stats.rx_fifo_errors++;
  128. -
  129. - /* There was a problem reading the mailbox, propagate
  130. - * error value.
  131. - */
  132. - if (unlikely(ret < 0))
  133. - return ERR_PTR(ret);
  134. -
  135. - return skb_error;
  136. - }
  137. -
  138. - cb = can_rx_offload_get_cb(skb);
  139. - ret = offload->mailbox_read(offload, cf, &cb->timestamp, n);
  140. + /* If queue is full drop frame */
  141. + if (unlikely(skb_queue_len(&offload->skb_queue) >
  142. + offload->skb_queue_len_max))
  143. + drop = true;
  144. + skb = offload->mailbox_read(offload, n, &timestamp, drop);
  145. /* Mailbox was empty. */
  146. - if (unlikely(!ret)) {
  147. - kfree_skb(skb);
  148. + if (unlikely(!skb))
  149. return NULL;
  150. - }
  151. -
  152. - /* There was a problem reading the mailbox, propagate error value. */
  153. - if (unlikely(ret < 0)) {
  154. - kfree_skb(skb);
  155. + /* There was a problem reading the mailbox, propagate
  156. + * error value.
  157. + */
  158. + if (unlikely(IS_ERR(skb))) {
  159. offload->dev->stats.rx_dropped++;
  160. offload->dev->stats.rx_fifo_errors++;
  161. - return ERR_PTR(ret);
  162. + return skb;
  163. }
  164. /* Mailbox was read. */
  165. + cb = can_rx_offload_get_cb(skb);
  166. + cb->timestamp = timestamp;
  167. +
  168. return skb;
  169. }
  170. --- a/include/linux/can/rx-offload.h
  171. +++ b/include/linux/can/rx-offload.h
  172. @@ -15,9 +15,9 @@
  173. struct can_rx_offload {
  174. struct net_device *dev;
  175. - unsigned int (*mailbox_read)(struct can_rx_offload *offload,
  176. - struct can_frame *cf,
  177. - u32 *timestamp, unsigned int mb);
  178. + struct sk_buff *(*mailbox_read)(struct can_rx_offload *offload,
  179. + unsigned int mb, u32 *timestamp,
  180. + bool drop);
  181. struct sk_buff_head skb_queue;
  182. u32 skb_queue_len_max;