Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
This commit is contained in:
@@ -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);
|
||||
struct sk_buff *skb;
|
||||
u8 len;
|
||||
|
||||
BUG_ON(idx >= priv->echo_skb_max);
|
||||
skb = __can_get_echo_skb(dev, idx, &len);
|
||||
if (!skb)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
netif_rx(skb);
|
||||
|
||||
netif_rx(priv->echo_skb[idx]);
|
||||
priv->echo_skb[idx] = NULL;
|
||||
|
||||
return dlc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_get_echo_skb);
|
||||
|
||||
|
@@ -135,13 +135,12 @@
|
||||
|
||||
/* FLEXCAN interrupt flag register (IFLAG) bits */
|
||||
/* Errata ERR005829 step7: Reserve first valid MB */
|
||||
#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8
|
||||
#define FLEXCAN_TX_MB_OFF_FIFO 9
|
||||
#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8
|
||||
#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0
|
||||
#define FLEXCAN_TX_MB_OFF_TIMESTAMP 1
|
||||
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
|
||||
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63
|
||||
#define FLEXCAN_IFLAG_MB(x) BIT(x)
|
||||
#define FLEXCAN_TX_MB 63
|
||||
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
|
||||
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1)
|
||||
#define FLEXCAN_IFLAG_MB(x) BIT(x & 0x1f)
|
||||
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
|
||||
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
|
||||
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
|
||||
@@ -259,9 +258,7 @@ struct flexcan_priv {
|
||||
struct can_rx_offload offload;
|
||||
|
||||
struct flexcan_regs __iomem *regs;
|
||||
struct flexcan_mb __iomem *tx_mb;
|
||||
struct flexcan_mb __iomem *tx_mb_reserved;
|
||||
u8 tx_mb_idx;
|
||||
u32 reg_ctrl_default;
|
||||
u32 reg_imask1_default;
|
||||
u32 reg_imask2_default;
|
||||
@@ -515,6 +512,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
|
||||
static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
const struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
struct can_frame *cf = (struct can_frame *)skb->data;
|
||||
u32 can_id;
|
||||
u32 data;
|
||||
@@ -537,17 +535,17 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
|
||||
|
||||
if (cf->can_dlc > 0) {
|
||||
data = be32_to_cpup((__be32 *)&cf->data[0]);
|
||||
priv->write(data, &priv->tx_mb->data[0]);
|
||||
priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]);
|
||||
}
|
||||
if (cf->can_dlc > 4) {
|
||||
data = be32_to_cpup((__be32 *)&cf->data[4]);
|
||||
priv->write(data, &priv->tx_mb->data[1]);
|
||||
priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]);
|
||||
}
|
||||
|
||||
can_put_echo_skb(skb, dev, 0);
|
||||
|
||||
priv->write(can_id, &priv->tx_mb->can_id);
|
||||
priv->write(ctrl, &priv->tx_mb->can_ctrl);
|
||||
priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id);
|
||||
priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl);
|
||||
|
||||
/* Errata ERR005829 step8:
|
||||
* Write twice INACTIVE(0x8) code to first MB.
|
||||
@@ -563,9 +561,13 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
|
||||
static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
|
||||
{
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
struct sk_buff *skb;
|
||||
struct can_frame *cf;
|
||||
bool rx_errors = false, tx_errors = false;
|
||||
u32 timestamp;
|
||||
|
||||
timestamp = priv->read(®s->timer) << 16;
|
||||
|
||||
skb = alloc_can_err_skb(dev, &cf);
|
||||
if (unlikely(!skb))
|
||||
@@ -612,17 +614,21 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
|
||||
if (tx_errors)
|
||||
dev->stats.tx_errors++;
|
||||
|
||||
can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
|
||||
can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
}
|
||||
|
||||
static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
|
||||
{
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
struct sk_buff *skb;
|
||||
struct can_frame *cf;
|
||||
enum can_state new_state, rx_state, tx_state;
|
||||
int flt;
|
||||
struct can_berr_counter bec;
|
||||
u32 timestamp;
|
||||
|
||||
timestamp = priv->read(®s->timer) << 16;
|
||||
|
||||
flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
|
||||
if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
|
||||
@@ -652,7 +658,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
|
||||
if (unlikely(new_state == CAN_STATE_BUS_OFF))
|
||||
can_bus_off(dev);
|
||||
|
||||
can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
|
||||
can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
}
|
||||
|
||||
static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
|
||||
@@ -720,9 +726,14 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
|
||||
priv->write(BIT(n - 32), ®s->iflag2);
|
||||
} else {
|
||||
priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
|
||||
priv->read(®s->timer);
|
||||
}
|
||||
|
||||
/* Read the Free Running Timer. It is optional but recommended
|
||||
* to unlock Mailbox as soon as possible and make it available
|
||||
* for reception.
|
||||
*/
|
||||
priv->read(®s->timer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -732,9 +743,9 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 iflag1, iflag2;
|
||||
|
||||
iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
|
||||
iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default &
|
||||
~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
|
||||
iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default &
|
||||
~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
|
||||
iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default;
|
||||
|
||||
return (u64)iflag2 << 32 | iflag1;
|
||||
}
|
||||
@@ -746,11 +757,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
irqreturn_t handled = IRQ_NONE;
|
||||
u32 reg_iflag1, reg_esr;
|
||||
u32 reg_iflag2, reg_esr;
|
||||
enum can_state last_state = priv->can.state;
|
||||
|
||||
reg_iflag1 = priv->read(®s->iflag1);
|
||||
|
||||
/* reception interrupt */
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
u64 reg_iflag;
|
||||
@@ -764,6 +773,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
u32 reg_iflag1;
|
||||
|
||||
reg_iflag1 = priv->read(®s->iflag1);
|
||||
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {
|
||||
handled = IRQ_HANDLED;
|
||||
can_rx_offload_irq_offload_fifo(&priv->offload);
|
||||
@@ -779,17 +791,22 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
||||
}
|
||||
}
|
||||
|
||||
reg_iflag2 = priv->read(®s->iflag2);
|
||||
|
||||
/* transmission complete interrupt */
|
||||
if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
|
||||
if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) {
|
||||
u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl);
|
||||
|
||||
handled = IRQ_HANDLED;
|
||||
stats->tx_bytes += can_get_echo_skb(dev, 0);
|
||||
stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload,
|
||||
0, reg_ctrl << 16);
|
||||
stats->tx_packets++;
|
||||
can_led_event(dev, CAN_LED_EVENT_TX);
|
||||
|
||||
/* after sending a RTR frame MB is in RX mode */
|
||||
priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
&priv->tx_mb->can_ctrl);
|
||||
priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
|
||||
®s->mb[FLEXCAN_TX_MB].can_ctrl);
|
||||
priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2);
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
|
||||
@@ -931,15 +948,13 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
|
||||
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
|
||||
FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
|
||||
FLEXCAN_MCR_IDAM_C;
|
||||
FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB);
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
|
||||
reg_mcr &= ~FLEXCAN_MCR_FEN;
|
||||
reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last);
|
||||
} else {
|
||||
reg_mcr |= FLEXCAN_MCR_FEN |
|
||||
FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
|
||||
}
|
||||
else
|
||||
reg_mcr |= FLEXCAN_MCR_FEN;
|
||||
|
||||
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
|
||||
priv->write(reg_mcr, ®s->mcr);
|
||||
|
||||
@@ -982,16 +997,17 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||
priv->write(reg_ctrl2, ®s->ctrl2);
|
||||
}
|
||||
|
||||
/* clear and invalidate all mailboxes first */
|
||||
for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
|
||||
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||
®s->mb[i].can_ctrl);
|
||||
}
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
|
||||
for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) {
|
||||
priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
|
||||
®s->mb[i].can_ctrl);
|
||||
}
|
||||
} else {
|
||||
/* clear and invalidate unused mailboxes first */
|
||||
for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) {
|
||||
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||
®s->mb[i].can_ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
|
||||
@@ -1000,7 +1016,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||
|
||||
/* mark TX mailbox as INACTIVE */
|
||||
priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
&priv->tx_mb->can_ctrl);
|
||||
®s->mb[FLEXCAN_TX_MB].can_ctrl);
|
||||
|
||||
/* acceptance mask/acceptance code (accept everything) */
|
||||
priv->write(0x0, ®s->rxgmask);
|
||||
@@ -1355,17 +1371,13 @@ static int flexcan_probe(struct platform_device *pdev)
|
||||
priv->devtype_data = devtype_data;
|
||||
priv->reg_xceiver = reg_xceiver;
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
|
||||
priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
|
||||
priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
|
||||
} else {
|
||||
priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
|
||||
else
|
||||
priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
|
||||
}
|
||||
priv->tx_mb = ®s->mb[priv->tx_mb_idx];
|
||||
|
||||
priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
|
||||
priv->reg_imask2_default = 0;
|
||||
priv->reg_imask1_default = 0;
|
||||
priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
|
||||
|
||||
priv->offload.mailbox_read = flexcan_mailbox_read;
|
||||
|
||||
|
@@ -24,6 +24,9 @@
|
||||
|
||||
#define RCAR_CAN_DRV_NAME "rcar_can"
|
||||
|
||||
#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
|
||||
BIT(CLKR_CLKEXT))
|
||||
|
||||
/* Mailbox configuration:
|
||||
* mailbox 60 - 63 - Rx FIFO mailboxes
|
||||
* mailbox 56 - 59 - Tx FIFO mailboxes
|
||||
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev)
|
||||
goto fail_clk;
|
||||
}
|
||||
|
||||
if (clock_select >= ARRAY_SIZE(clock_names)) {
|
||||
if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) {
|
||||
err = -EINVAL;
|
||||
dev_err(&pdev->dev, "invalid CAN clock selected\n");
|
||||
goto fail_clk;
|
||||
|
@@ -211,7 +211,54 @@ 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_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb)
|
||||
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_queue_tail(struct can_rx_offload *offload,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (skb_queue_len(&offload->skb_queue) >
|
||||
offload->skb_queue_len_max)
|
||||
@@ -222,7 +269,7 @@ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_b
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(can_rx_offload_irq_queue_err_skb);
|
||||
EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail);
|
||||
|
||||
static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight)
|
||||
{
|
||||
|
@@ -760,7 +760,7 @@ static int hi3110_open(struct net_device *net)
|
||||
{
|
||||
struct hi3110_priv *priv = netdev_priv(net);
|
||||
struct spi_device *spi = priv->spi;
|
||||
unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING;
|
||||
unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH;
|
||||
int ret;
|
||||
|
||||
ret = open_candev(net);
|
||||
|
@@ -528,7 +528,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||
context = &priv->tx_contexts[i];
|
||||
|
||||
context->echo_index = i;
|
||||
can_put_echo_skb(skb, netdev, context->echo_index);
|
||||
++priv->active_tx_contexts;
|
||||
if (priv->active_tx_contexts >= (int)dev->max_tx_urbs)
|
||||
netif_stop_queue(netdev);
|
||||
@@ -553,7 +552,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||
dev_kfree_skb(skb);
|
||||
spin_lock_irqsave(&priv->tx_contexts_lock, flags);
|
||||
|
||||
can_free_echo_skb(netdev, context->echo_index);
|
||||
context->echo_index = dev->max_tx_urbs;
|
||||
--priv->active_tx_contexts;
|
||||
netif_wake_queue(netdev);
|
||||
@@ -564,6 +562,8 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||
|
||||
context->priv = priv;
|
||||
|
||||
can_put_echo_skb(skb, netdev, context->echo_index);
|
||||
|
||||
usb_fill_bulk_urb(urb, dev->udev,
|
||||
usb_sndbulkpipe(dev->udev,
|
||||
dev->bulk_out->bEndpointAddress),
|
||||
|
@@ -1019,6 +1019,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
||||
new_state : CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
can_change_state(netdev, cf, tx_state, rx_state);
|
||||
|
||||
if (priv->can.restart_ms &&
|
||||
old_state >= CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF) {
|
||||
@@ -1028,11 +1033,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
||||
|
||||
can_bus_off(netdev);
|
||||
}
|
||||
|
||||
if (priv->can.restart_ms &&
|
||||
old_state >= CAN_STATE_BUS_OFF &&
|
||||
new_state < CAN_STATE_BUS_OFF)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
|
@@ -35,10 +35,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/error.h>
|
||||
|
||||
#define UCAN_DRIVER_NAME "ucan"
|
||||
#define UCAN_MAX_RX_URBS 8
|
||||
/* the CAN controller needs a while to enable/disable the bus */
|
||||
@@ -1575,11 +1571,8 @@ err_firmware_needs_update:
|
||||
/* disconnect the device */
|
||||
static void ucan_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_device *udev;
|
||||
struct ucan_priv *up = usb_get_intfdata(intf);
|
||||
|
||||
udev = interface_to_usbdev(intf);
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
|
||||
if (up) {
|
||||
|
Reference in New Issue
Block a user