summaryrefslogtreecommitdiff
path: root/drivers/net/can/dev.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-11-13 19:43:05 +0300
committerDavid S. Miller <davem@davemloft.net>2018-11-13 19:43:05 +0300
commit11123ab9d90c5f426beadfe01507616c3654b06d (patch)
treed22e05eb886a670a887ee3464e17bdf307b5c178 /drivers/net/can/dev.c
parent77e461d14ed141253573eeeb4d34eccc51e38328 (diff)
parentd788905f68fd4714c82936f6f7f1d3644d7ae7ef (diff)
downloadlinux-11123ab9d90c5f426beadfe01507616c3654b06d.tar.xz
Merge tag 'linux-can-fixes-for-4.20-20181109' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2018-11-09 this is a pull request of 20 patches for net/master. First we have a patch by Oliver Hartkopp which changes the raw socket's raw_sendmsg() to return an error value if the user tries to send a CANFD frame to a CAN-2.0 device. The next two patches are by Jimmy Assarsson and fix potential problems in the kvaser_usb driver. YueHaibing's patches for the ucan driver fix a compile time warning and remove a duplicate include. Eugeniu Rosca patch adds more binding documentation to the rcar_can driver bindings. The next two patches are by Fabrizio Castro for the rcar_can driver and fixes a problem in the driver's probe function and document the r8a774a1 binding. Lukas Wunner's patch fixes a recpetion problem in hi311x driver by switching from edge to level triggered interruts. The next three patches all target the flexcan driver. Pankaj Bansal's patch unconditionally unlocks the last mailbox used for RX. Alexander Stein provides a better workaround for a hardware limitation when sending RTR frames, by using the last mailbox for TX, resulting in fewer lost frames. The patch by me simplyfies the driver, by making a runtime value a compile time constant. The following 4 patches are by me and provide the groundwork for the next patches by Oleksij Rempel. To avoid code duplication common code in the common CAN driver infrastructure is factured out and error handling is cleaned up. The next 4 patches are by Oleksij Rempel and fix the problem in the flexcan driver that other processes see TX frames arrive out of order with ragards to a RX'ed frame (which are send by a different system on the CAN bus as the result of our TX frame). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c48
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,
}
EXPORT_SYMBOL_GPL(can_put_echo_skb);
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct sk_buff *skb = priv->echo_skb[idx];
+ struct canfd_frame *cf;
+
+ if (idx >= priv->echo_skb_max) {
+ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+ __func__, idx, priv->echo_skb_max);
+ return NULL;
+ }
+
+ if (!skb) {
+ netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
+ __func__, idx);
+ return NULL;
+ }
+
+ /* Using "struct canfd_frame::len" for the frame
+ * length is supported on both CAN and CANFD frames.
+ */
+ cf = (struct canfd_frame *)skb->data;
+ *len_ptr = cf->len;
+ priv->echo_skb[idx] = NULL;
+
+ return skb;
+}
+
/*
* Get the skb from the stack and loop it back locally
*
@@ -486,22 +514,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
*/
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
{
- struct can_priv *priv = netdev_priv(dev);
-
- BUG_ON(idx >= priv->echo_skb_max);
-
- if (priv->echo_skb[idx]) {
- struct sk_buff *skb = priv->echo_skb[idx];
- struct can_frame *cf = (struct can_frame *)skb->data;
- u8 dlc = cf->can_dlc;
+ struct sk_buff *skb;
+ u8 len;
- netif_rx(priv->echo_skb[idx]);
- priv->echo_skb[idx] = NULL;
+ skb = __can_get_echo_skb(dev, idx, &len);
+ if (!skb)
+ return 0;
- return dlc;
- }
+ netif_rx(skb);
- return 0;
+ return len;
}
EXPORT_SYMBOL_GPL(can_get_echo_skb);