patch-2.4.18 linux/drivers/net/bmac.c

Next file: linux/drivers/net/bonding.c
Previous file: linux/drivers/net/au1000_eth.c
Back to the patch index
Back to the overall index

diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/drivers/net/bmac.c linux/drivers/net/bmac.c
@@ -22,7 +22,8 @@
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/feature.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
 #ifdef CONFIG_PMAC_PBOOK
 #include <linux/adb.h>
 #include <linux/pmu.h>
@@ -155,7 +156,7 @@
 static void bmac_start_chip(struct net_device *dev);
 static void bmac_init_chip(struct net_device *dev);
 static void bmac_init_registers(struct net_device *dev);
-static void bmac_reset_chip(struct net_device *dev);
+static void bmac_enable_and_reset_chip(struct net_device *dev);
 static int bmac_set_address(struct net_device *dev, void *addr);
 static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs);
 static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
@@ -229,21 +230,18 @@
 }
 
 static void
-bmac_reset_chip(struct net_device *dev)
+bmac_enable_and_reset_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = (struct bmac_data *) dev->priv;
 	volatile struct dbdma_regs *rd = bp->rx_dma;
 	volatile struct dbdma_regs *td = bp->tx_dma;
 
-	dbdma_reset(rd);
-	dbdma_reset(td);
+	if (rd)
+		dbdma_reset(rd);
+	if (td)
+		dbdma_reset(td);
 
-	feature_set(bp->node, FEATURE_BMac_IO_enable);
-	udelay(10000);
-	feature_set(bp->node, FEATURE_BMac_reset);
-	udelay(10000);
-	feature_clear(bp->node, FEATURE_BMac_reset);
-	udelay(10000);
+	pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 1);
 }
 
 #define MIFDELAY	udelay(10)
@@ -522,10 +520,7 @@
 				}
 			}
 		}
-		feature_set(bp->node, FEATURE_BMac_reset);
-		mdelay(10);
-		feature_clear(bp->node, FEATURE_BMac_IO_enable);
-		mdelay(10);
+		pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
 		break;
 	case PBOOK_WAKE:
 		/* see if this is enough */
@@ -1267,7 +1262,7 @@
 	unsigned char *data;
 
 	save_flags(flags); cli();
-	bmac_reset_chip(dev);
+	bmac_enable_and_reset_chip(dev);
 	bmac_init_tx_ring(bp);
 	bmac_init_rx_ring(bp);
 	bmac_init_chip(dev);
@@ -1350,14 +1345,30 @@
 		       bmac->full_name);
 		return;
 	}
+	bp = (struct bmac_data *) dev->priv;
 	SET_MODULE_OWNER(dev);
+	bp->node = bmac;
 
+	if (!request_OF_resource(bmac, 0, " (bmac)")) {
+		printk(KERN_ERR "BMAC: can't request IO resource !\n");
+		goto err_out;
+	}
+	if (!request_OF_resource(bmac, 1, " (bmac tx dma)")) {
+		printk(KERN_ERR "BMAC: can't request TX DMA resource !\n");
+		goto err_out;
+	}
+
+	if (!request_OF_resource(bmac, 2, " (bmac rx dma)")) {
+		printk(KERN_ERR "BMAC: can't request RX DMA resource !\n");
+		goto err_out;
+	}
 	dev->base_addr = (unsigned long)
 		ioremap(bmac->addrs[0].address, bmac->addrs[0].size);
 	if (!dev->base_addr)
 		goto err_out;
 	dev->irq = bmac->intrs[0].line;
 
+	bmac_enable_and_reset_chip(dev);
 	bmwrite(dev, INTDISABLE, DisableAll);
 
 	printk(KERN_INFO "%s: BMAC%s at", dev->name, (is_bmac_plus? "+": ""));
@@ -1369,6 +1380,10 @@
 	XXDEBUG((", base_addr=%#0lx", dev->base_addr));
 	printk("\n");
 
+	/* Enable chip without interrupts for now */
+	bmac_enable_and_reset_chip(dev);
+	bmwrite(dev, INTDISABLE, DisableAll);
+
 	dev->open = bmac_open;
 	dev->stop = bmac_close;
 	dev->hard_start_xmit = bmac_output;
@@ -1380,7 +1395,6 @@
 	if (bmac_verify_checksum(dev) != 0)
 		goto err_out_iounmap;
 
-	bp = (struct bmac_data *) dev->priv;
 	bp->is_bmac_plus = is_bmac_plus;
 	bp->tx_dma = (volatile struct dbdma_regs *)
 		ioremap(bmac->addrs[1].address, bmac->addrs[1].size);
@@ -1399,7 +1413,6 @@
 	bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1);
 	skb_queue_head_init(bp->queue);
 
-	bp->node = bmac;
 	memset((char *) bp->tx_cmds, 0,
 	       (N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
 	/*     init_timer(&bp->tx_timeout); */
@@ -1421,6 +1434,12 @@
 		goto err_out_irq1;
 	}
 
+	/* Mask chip interrupts and disable chip, will be
+	 * re-enabled on open()
+	 */
+	disable_irq(dev->irq);
+	pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
+	
 	bp->next_bmac = bmac_devs;
 	bmac_devs = dev;
 	return;
@@ -1436,6 +1455,12 @@
 err_out_iounmap:
 	iounmap((void *)dev->base_addr);
 err_out:
+	if (bp->node) {
+		release_OF_resource(bp->node, 0);
+		release_OF_resource(bp->node, 1);
+		release_OF_resource(bp->node, 2);
+		pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
+	}
 	unregister_netdev(dev);
 	kfree(dev);
 }
@@ -1447,6 +1472,7 @@
 	/* reset the chip */
 	bp->opened = 1;
 	bmac_reset_and_enable(dev);
+	enable_irq(dev->irq);
 	dev->flags |= IFF_RUNNING;
 	return 0;
 }
@@ -1459,6 +1485,7 @@
 	unsigned short config;
 	int i;
 
+	bp->sleeping = 1;
 	dev->flags &= ~(IFF_UP | IFF_RUNNING);
 
 	/* disable rx and tx */
@@ -1492,6 +1519,8 @@
 	XXDEBUG(("bmac: all bufs freed\n"));
 
 	bp->opened = 0;
+	disable_irq(dev->irq);
+	pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
 
 	return 0;
 }
@@ -1561,7 +1590,7 @@
 	bmwrite(dev, TXCFG, (config & ~TxMACEnable));
 	out_le32(&td->control, DBDMA_CLEAR(RUN|PAUSE|FLUSH|WAKE|ACTIVE|DEAD));
 	printk(KERN_ERR "bmac: transmit timeout - resetting\n");
-	bmac_reset_chip(dev);
+	bmac_enable_and_reset_chip(dev);
 
 	/* restart rx dma */
 	cp = bus_to_virt(ld_le32(&rd->cmdptr));
@@ -1683,11 +1712,15 @@
 		bp = (struct bmac_data *) dev->priv;
 		bmac_devs = bp->next_bmac;
 
+		unregister_netdev(dev);
+
+		release_OF_resource(bp->node, 0);
+		release_OF_resource(bp->node, 1);
+		release_OF_resource(bp->node, 2);
 		free_irq(dev->irq, dev);
 		free_irq(bp->tx_dma_intr, dev);
 		free_irq(bp->rx_dma_intr, dev);
 
-		unregister_netdev(dev);
 		kfree(dev);
 	} while (bmac_devs != NULL);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)