diff options
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/dev.c | 10 | ||||
-rw-r--r-- | drivers/net/can/flexcan.c | 23 |
2 files changed, 22 insertions, 11 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index d0f8c7e67e7d..f0123ef7d89d 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -315,16 +315,24 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); * is handled in the device driver. The driver must protect * access to priv->echo_skb, if necessary. */ -void can_get_echo_skb(struct net_device *dev, unsigned int idx) +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; + netif_rx(priv->echo_skb[idx]); priv->echo_skb[idx] = NULL; + + return dlc; } + + return 0; } EXPORT_SYMBOL_GPL(can_get_echo_skb); diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 920b8a01f9cb..d3b1342ca727 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -126,7 +126,8 @@ (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) /* FLEXCAN interrupt flag register (IFLAG) bits */ -#define FLEXCAN_TX_BUF_ID 8 +#define FLEXCAN_RESERVED_BUF_ID 8 +#define FLEXCAN_TX_BUF_ID 13 #define FLEXCAN_IFLAG_BUF(x) BIT(x) #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) @@ -284,7 +285,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev, static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; struct flexcan_regs __iomem *regs = priv->base; struct can_frame *cf = (struct can_frame *)skb->data; u32 can_id; @@ -314,13 +314,15 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); } + can_put_echo_skb(skb, dev, 0); + writel(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); writel(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); - kfree_skb(skb); - - /* tx_packets is incremented in flexcan_irq */ - stats->tx_bytes += cf->can_dlc; + if (priv->version == FLEXCAN_VER_10_0_12) { + writel(0x0, ®s->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl); + writel(0x0, ®s->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl); + } return NETDEV_TX_OK; } @@ -633,7 +635,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) /* transmission complete interrupt */ if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { - /* tx_bytes is incremented in flexcan_start_xmit */ + stats->tx_bytes += can_get_echo_skb(dev, 0); stats->tx_packets++; writel((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); netif_wake_queue(dev); @@ -722,13 +724,14 @@ static int flexcan_chip_start(struct net_device *dev) * enable warning int * choose format C * enable self wakeup + * disable local echo * */ reg_mcr = readl(®s->mcr); reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_WAK_MSK | - FLEXCAN_MCR_SLF_WAK; + FLEXCAN_MCR_SLF_WAK | FLEXCAN_MCR_SRX_DIS; dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); writel(reg_mcr, ®s->mcr); @@ -1008,7 +1011,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) goto failed_map; } - dev = alloc_candev(sizeof(struct flexcan_priv), 0); + dev = alloc_candev(sizeof(struct flexcan_priv), 1); if (!dev) { err = -ENOMEM; goto failed_alloc; @@ -1016,7 +1019,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) dev->netdev_ops = &flexcan_netdev_ops; dev->irq = irq; - dev->flags |= IFF_ECHO; /* we support local echo in hardware */ + dev->flags |= IFF_ECHO; priv = netdev_priv(dev); priv->can.clock.freq = clk_get_rate(clk); |