]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/gianfar.c
[PATCH] skge: don't clear MC state on link down
[linux-2.6-omap-h63xx.git] / drivers / net / gianfar.c
index ba960913c034f08d8485235b1de3ccb1b04bf187..6bf18c82083dd1ee4adf57c82ac7402b8fb54cf8 100644 (file)
@@ -119,9 +119,9 @@ struct sk_buff *gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp);
 static struct net_device_stats *gfar_get_stats(struct net_device *dev);
 static int gfar_set_mac_address(struct net_device *dev);
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
-static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t gfar_error(int irq, void *dev_id);
+static irqreturn_t gfar_transmit(int irq, void *dev_id);
+static irqreturn_t gfar_interrupt(int irq, void *dev_id);
 static void adjust_link(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int init_phy(struct net_device *dev);
@@ -133,6 +133,9 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
 #ifdef CONFIG_GFAR_NAPI
 static int gfar_poll(struct net_device *dev, int *budget);
 #endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void gfar_netpoll(struct net_device *dev);
+#endif
 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
 static void gfar_vlan_rx_register(struct net_device *netdev,
@@ -143,7 +146,7 @@ void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
 
-extern struct ethtool_ops gfar_ethtool_ops;
+extern const struct ethtool_ops gfar_ethtool_ops;
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
@@ -259,6 +262,9 @@ static int gfar_probe(struct platform_device *pdev)
 #ifdef CONFIG_GFAR_NAPI
        dev->poll = gfar_poll;
        dev->weight = GFAR_DEV_WEIGHT;
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = gfar_netpoll;
 #endif
        dev->stop = gfar_close;
        dev->get_stats = gfar_get_stats;
@@ -1063,7 +1069,7 @@ static void gfar_vlan_rx_register(struct net_device *dev,
                tempval |= TCTRL_VLINS;
 
                gfar_write(&priv->regs->tctrl, tempval);
-               
+
                /* Enable VLAN tag extraction */
                tempval = gfar_read(&priv->regs->rctrl);
                tempval |= RCTRL_VLEX;
@@ -1173,7 +1179,7 @@ static void gfar_timeout(struct net_device *dev)
 }
 
 /* Interrupt Handler for Transmit complete */
-static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_transmit(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1305,7 +1311,7 @@ static inline void count_errors(unsigned short status, struct gfar_private *priv
        }
 }
 
-irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t gfar_receive(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1536,8 +1542,35 @@ static int gfar_poll(struct net_device *dev, int *budget)
 }
 #endif
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void gfar_netpoll(struct net_device *dev)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+
+       /* If the device has multiple interrupts, run tx/rx */
+       if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
+               disable_irq(priv->interruptTransmit);
+               disable_irq(priv->interruptReceive);
+               disable_irq(priv->interruptError);
+               gfar_interrupt(priv->interruptTransmit, dev);
+               enable_irq(priv->interruptError);
+               enable_irq(priv->interruptReceive);
+               enable_irq(priv->interruptTransmit);
+       } else {
+               disable_irq(priv->interruptTransmit);
+               gfar_interrupt(priv->interruptTransmit, dev);
+               enable_irq(priv->interruptTransmit);
+       }
+}
+#endif
+
 /* The interrupt handler for devices with one interrupt */
-static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1550,11 +1583,11 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        /* Check for reception */
        if ((events & IEVENT_RXF0) || (events & IEVENT_RXB0))
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
        /* Check for transmit completion */
        if ((events & IEVENT_TXF) || (events & IEVENT_TXB))
-               gfar_transmit(irq, dev_id, regs);
+               gfar_transmit(irq, dev_id);
 
        /* Update error statistics */
        if (events & IEVENT_TXE) {
@@ -1578,7 +1611,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                priv->stats.rx_errors++;
                priv->extra_stats.rx_bsy++;
 
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
 #ifndef CONFIG_GFAR_NAPI
                /* Clear the halt bit in RSTAT */
@@ -1708,9 +1741,6 @@ static void gfar_set_multi(struct net_device *dev)
        u32 tempval;
 
        if(dev->flags & IFF_PROMISC) {
-               if (netif_msg_drv(priv))
-                       printk(KERN_INFO "%s: Entering promiscuous mode.\n",
-                                       dev->name);
                /* Set RCTRL to PROM */
                tempval = gfar_read(&regs->rctrl);
                tempval |= RCTRL_PROM;
@@ -1721,7 +1751,7 @@ static void gfar_set_multi(struct net_device *dev)
                tempval &= ~(RCTRL_PROM);
                gfar_write(&regs->rctrl, tempval);
        }
-       
+
        if(dev->flags & IFF_ALLMULTI) {
                /* Set the hash to rx all multicast frames */
                gfar_write(&regs->igaddr0, 0xffffffff);
@@ -1860,7 +1890,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
 }
 
 /* GFAR error interrupt handler */
-static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_error(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1901,7 +1931,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
                priv->stats.rx_errors++;
                priv->extra_stats.rx_bsy++;
 
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
 #ifndef CONFIG_GFAR_NAPI
                /* Clear the halt bit in RSTAT */
@@ -1957,7 +1987,7 @@ static int __init gfar_init(void)
 
        if (err)
                gfar_mdio_exit();
-       
+
        return err;
 }