Skip to content

Commit

Permalink
can: rx-offload: introduce can_rx_offload_get_echo_skb() and can_rx_o…
Browse files Browse the repository at this point in the history
…ffload_queue_sorted() functions

Current CAN framework can't guarantee proper/chronological order
of RX and TX-ECHO messages. To make this possible, drivers should use
this functions instead of can_get_echo_skb().

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
olerem authored and marckleinebudde committed Nov 9, 2018
1 parent 7da11ba commit 55059f2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
46 changes: 46 additions & 0 deletions drivers/net/can/rx-offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,52 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload)
}
EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo);

int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
struct sk_buff *skb, u32 timestamp)
{
struct can_rx_offload_cb *cb;
unsigned long flags;

if (skb_queue_len(&offload->skb_queue) >
offload->skb_queue_len_max)
return -ENOMEM;

cb = can_rx_offload_get_cb(skb);
cb->timestamp = timestamp;

spin_lock_irqsave(&offload->skb_queue.lock, flags);
__skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare);
spin_unlock_irqrestore(&offload->skb_queue.lock, flags);

can_rx_offload_schedule(offload);

return 0;
}
EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted);

unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
unsigned int idx, u32 timestamp)
{
struct net_device *dev = offload->dev;
struct net_device_stats *stats = &dev->stats;
struct sk_buff *skb;
u8 len;
int err;

skb = __can_get_echo_skb(dev, idx, &len);
if (!skb)
return 0;

err = can_rx_offload_queue_sorted(offload, skb, timestamp);
if (err) {
stats->rx_errors++;
stats->tx_fifo_errors++;
}

return len;
}
EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb);

int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb)
{
if (skb_queue_len(&offload->skb_queue) >
Expand Down
4 changes: 4 additions & 0 deletions include/linux/can/rx-offload.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *
int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight);
int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 reg);
int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload);
int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
struct sk_buff *skb, u32 timestamp);
unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
unsigned int idx, u32 timestamp);
int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb);
void can_rx_offload_reset(struct can_rx_offload *offload);
void can_rx_offload_del(struct can_rx_offload *offload);
Expand Down

0 comments on commit 55059f2

Please sign in to comment.