diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/can/dev.c | 10 | ||||
-rw-r--r-- | drivers/net/can/flexcan.c | 23 | ||||
-rwxr-xr-x | drivers/net/fec.c | 17 |
3 files changed, 39 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); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 69e4a57ed51b..ebb09eb9a6f2 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -27,6 +27,7 @@ #include <linux/string.h> #include <linux/ptrace.h> #include <linux/errno.h> +#include <linux/gpio.h> #include <linux/ioport.h> #include <linux/slab.h> #include <linux/interrupt.h> @@ -1872,6 +1873,17 @@ fec_probe(struct platform_device *pdev) if (pdata) fep->phy_interface = pdata->phy; +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + gpio_request(pdata->gpio_irq, "gpio_enet_irq"); + gpio_direction_input(pdata->gpio_irq); + + irq = gpio_to_irq(pdata->gpio_irq); + ret = request_irq(irq, fec_enet_interrupt, + IRQF_TRIGGER_RISING, + pdev->name, ndev); + if (ret) + goto failed_irq; +#else /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); @@ -1886,6 +1898,7 @@ fec_probe(struct platform_device *pdev) goto failed_irq; } } +#endif fep->clk = clk_get(&pdev->dev, "fec_clk"); if (IS_ERR(fep->clk)) { @@ -1936,11 +1949,15 @@ failed_init: clk_disable(fep->clk); clk_put(fep->clk); failed_clk: +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + free_irq(irq, ndev); +#else for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); if (irq > 0) free_irq(irq, ndev); } +#endif failed_irq: iounmap(fep->hwp); failed_ioremap: |