diff options
author | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:34:03 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:34:03 -0500 |
commit | 1ec28f8b8ada4e4f77d1af006a3a474f4f83b8e3 (patch) | |
tree | 2e810e02a66cdec0bc82a8555796b7083ad03416 /drivers/net/can/dev.c | |
parent | 61647c77cb15354a329cbb36fe7a2253b36b51b1 (diff) | |
parent | 2e6e902d185027f8e3cb8b7305238f7e35d6a436 (diff) |
Merge v4.20-rc4 into drm-next
Requested by Boris Brezillon for some vc4 fixes that are needed for future vc4 work.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r-- | drivers/net/can/dev.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 49163570a63a..3b3f88ffab53 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -477,6 +477,34 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
477 | } | 477 | } |
478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); | 478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); |
479 | 479 | ||
480 | struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) | ||
481 | { | ||
482 | struct can_priv *priv = netdev_priv(dev); | ||
483 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
484 | struct canfd_frame *cf; | ||
485 | |||
486 | if (idx >= priv->echo_skb_max) { | ||
487 | netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", | ||
488 | __func__, idx, priv->echo_skb_max); | ||
489 | return NULL; | ||
490 | } | ||
491 | |||
492 | if (!skb) { | ||
493 | netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n", | ||
494 | __func__, idx); | ||
495 | return NULL; | ||
496 | } | ||
497 | |||
498 | /* Using "struct canfd_frame::len" for the frame | ||
499 | * length is supported on both CAN and CANFD frames. | ||
500 | */ | ||
501 | cf = (struct canfd_frame *)skb->data; | ||
502 | *len_ptr = cf->len; | ||
503 | priv->echo_skb[idx] = NULL; | ||
504 | |||
505 | return skb; | ||
506 | } | ||
507 | |||
480 | /* | 508 | /* |
481 | * Get the skb from the stack and loop it back locally | 509 | * Get the skb from the stack and loop it back locally |
482 | * | 510 | * |
@@ -486,22 +514,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); | |||
486 | */ | 514 | */ |
487 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) | 515 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) |
488 | { | 516 | { |
489 | struct can_priv *priv = netdev_priv(dev); | 517 | struct sk_buff *skb; |
490 | 518 | u8 len; | |
491 | BUG_ON(idx >= priv->echo_skb_max); | ||
492 | |||
493 | if (priv->echo_skb[idx]) { | ||
494 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
495 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
496 | u8 dlc = cf->can_dlc; | ||
497 | 519 | ||
498 | netif_rx(priv->echo_skb[idx]); | 520 | skb = __can_get_echo_skb(dev, idx, &len); |
499 | priv->echo_skb[idx] = NULL; | 521 | if (!skb) |
522 | return 0; | ||
500 | 523 | ||
501 | return dlc; | 524 | netif_rx(skb); |
502 | } | ||
503 | 525 | ||
504 | return 0; | 526 | return len; |
505 | } | 527 | } |
506 | EXPORT_SYMBOL_GPL(can_get_echo_skb); | 528 | EXPORT_SYMBOL_GPL(can_get_echo_skb); |
507 | 529 | ||