--- linux-2.2.17pre13-ben1.orig/drivers/net/Config.in	Sun Jul 23 06:24:55 2000
+++ linux-2.2.17pre13-ben1/drivers/net/Config.in	Tue Nov  7 17:38:49 2000
@@ -50,6 +50,9 @@
       bool 'Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT
     fi
     tristate 'BMAC (G3 ethernet) support' CONFIG_BMAC
+    if [ "$CONFIG_BMAC" != "n" ]; then
+      bool 'Enable non-streaming Tranmit DMA support' CONFIG_BMAC_NO_STREAM_XMIT_DMA
+    fi
     tristate 'GMAC (G4/iBook ethernet) support' CONFIG_GMAC
     tristate 'Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E
   fi
--- linux-2.2.17pre13-ben1.orig/drivers/net/bmac.c	Thu Jul 20 05:06:59 2000
+++ linux-2.2.17pre13-ben1/drivers/net/bmac.c	Tue Nov  7 18:01:43 2000
@@ -49,7 +49,12 @@
 /* Bits in transmit DMA status */
 #define TX_DMA_ERR	0x80
 
-#define XXDEBUG(args)
+#undef CONFIG_BMAC_DEBUG
+#ifndef CONFIG_BMAC_DEBUG
+#define XXDEBUG(args...)
+#else /* CONFIG_BMAC_DEBUG */
+#define XXDEBUG(args...) printk(KERN_INFO args)
+#endif /* CONFIG_BMAC_DEBUG */
 
 struct bmac_data {
 	/* volatile struct bmac *bmac; */
@@ -333,7 +338,7 @@
 	unsigned short *pWord16;
 	int i;
 
-	/* XXDEBUG(("bmac: enter init_registers\n")); */
+	XXDEBUG ("bmac: enter init_registers\n") ;
 
 	bmwrite(dev, RXRST, RxResetValue);
 	bmwrite(dev, TXRST, TxResetBit);
@@ -518,7 +523,7 @@
 	unsigned long flags;
 	int i;
 
-	XXDEBUG(("bmac: enter set_address\n"));
+	XXDEBUG ("bmac: enter set_address\n") ;
 	save_flags(flags); cli();
 
 	for (i = 0; i < 6; ++i) {
@@ -531,7 +536,7 @@
 	bmwrite(dev, MADD2, *pWord16);
 
 	restore_flags(flags);
-	XXDEBUG(("bmac: exit set_address\n"));
+	XXDEBUG ("bmac: exit set_address\n") ;
 	return 0;
 }
 
@@ -563,7 +568,12 @@
 	vaddr = skb->data;
 	baddr = virt_to_bus(vaddr);
 
+#ifndef CONFIG_BMAC_NO_STREAM_XMIT_DMA
 	dbdma_setcmd(cp, (OUTPUT_LAST | INTR_ALWAYS | WAIT_IFCLR), len, baddr, 0);
+#else /* CONFIG_BMAC_NO_STREAM_XMIT_DMA */
+	dbdma_setcmd(cp, (OUTPUT_LAST | INTR_NEVER | WAIT_IFCLR), len, baddr, 0);
+	/* dbdma_setcmd(cp, (OUTPUT_LAST | INTR_NEVER | WAIT_NEVER | BR_NEVER | KEY_SYSTEM), len, baddr, 0);*/
+#endif /* CONFIG_BMAC_NO_STREAM_XMIT_DMA */
 }
 
 static void
@@ -650,14 +660,14 @@
 	int i;
 
 	/* see if there's a free slot in the tx ring */
-	/* XXDEBUG(("bmac_xmit_start: empty=%d fill=%d\n", */
-	/* 	     bp->tx_empty, bp->tx_fill)); */
+	XXDEBUG ("bmac_xmit_packet: empty=%d fill=%d\n",
+	 	     bp->tx_empty, bp->tx_fill) ;
 	i = bp->tx_fill + 1;
 	if (i >= N_TX_RING) i = 0;
 	if (i == bp->tx_empty) {
 		dev->tbusy = 1;
 		bp->tx_fullup = 1;
-		XXDEBUG(("bmac_transmit_packet: tx ring full\n"));
+		XXDEBUG ("bmac_transmit_packet: tx ring full\n") ;
 		return -1;		/* can't take it at the moment */
 	}
 
@@ -692,7 +702,7 @@
 	save_flags(flags); cli();
 
 	if (++rxintcount < 10) {
-		XXDEBUG(("bmac_rxdma_intr\n"));
+		XXDEBUG ("bmac_rxdma_intr\n") ;
 	}
 
 	last = -1;
@@ -739,7 +749,7 @@
 	dbdma_continue(rd);
 
 	if (rxintcount < 10) {
-		XXDEBUG(("bmac_rxdma_intr done\n"));
+		XXDEBUG ("bmac_rxdma_intr done\n") ;
 	}
 }
 
@@ -756,7 +766,7 @@
 	save_flags(flags); cli();
 
 	if (txintcount++ < 10) {
-		XXDEBUG(("bmac_txdma_intr\n"));
+		XXDEBUG ("bmac_txdma_intr\n") ;
 	}
 
 	/*     del_timer(&bp->tx_timeout); */
@@ -766,7 +776,7 @@
 		cp = &bp->tx_cmds[bp->tx_empty];
 		stat = ld_le16(&cp->xfer_status);
 		if (txintcount < 10) {
-			XXDEBUG(("bmac_txdma_xfer_stat=%#0x\n", stat));
+			XXDEBUG ("bmac_txdma_xfer_stat=%#0x\n", stat) ;
 		}
 		if (!(stat & ACTIVE)) break;
 
@@ -777,8 +787,8 @@
 		bp->tx_bufs[bp->tx_empty] = NULL;
 		bp->tx_fullup = 0;
 		dev->tbusy = 0;
-		/* XXDEBUG(("bmac_intr: cleared tbusy, empty=%d fill=%d\n", */
-		/* 		 i, bp->tx_fill)); */
+		XXDEBUG ("bmac_txdma_intr: cleared tbusy, empty=%d fill=%d\n",
+		 		 bp->tx_empty, bp->tx_fill) ;
 		mark_bh(NET_BH);
 		if (++bp->tx_empty >= N_TX_RING) bp->tx_empty = 0;
 		if (bp->tx_empty == bp->tx_fill) break;
@@ -787,7 +797,7 @@
 	restore_flags(flags);
 
 	if (txintcount < 10) {
-		XXDEBUG(("bmac_txdma_intr done->bmac_start\n"));
+		XXDEBUG ("bmac_txdma_intr done->bmac_start\n") ;
 	}
 
 	bmac_start(dev);
@@ -846,7 +856,7 @@
 {	
 	unsigned int newcrc;
 
-	XXDEBUG(("bmac_crc: addr=%#04x, %#04x, %#04x\n", *address, address[1], address[2]));
+	XXDEBUG ("bmac_crc: addr=%#04x, %#04x, %#04x\n", *address, address[1], address[2]) ;
 	newcrc = crc416(0xffffffff, *address);	/* address bits 47 - 32 */
 	newcrc = crc416(newcrc, address[1]);	/* address bits 31 - 16 */
 	newcrc = crc416(newcrc, address[2]);	/* address bits 15 - 0  */
@@ -940,12 +950,12 @@
 bmac_add_multi(struct device *dev,
 	       struct bmac_data *bp, unsigned char *addr)
 {
-	/* XXDEBUG(("bmac: enter bmac_add_multi\n")); */
+	XXDEBUG ("bmac: enter bmac_add_multi\n") ;
 	bmac_addhash(bp, addr);
 	bmac_rx_off(dev);
 	bmac_update_hash_table_mask(dev, bp);
 	bmac_rx_on(dev, 1, (dev->flags & IFF_PROMISC)? 1 : 0);
-	/* XXDEBUG(("bmac: exit bmac_add_multi\n")); */
+	XXDEBUG ("bmac: exit bmac_add_multi\n") ;
 }
 
 static void
@@ -973,34 +983,34 @@
 	unsigned short rx_cfg;
 	int i;
 
-	XXDEBUG(("bmac: enter bmac_set_multicast, n_addrs=%d\n", num_addrs));
+	XXDEBUG ("bmac: enter bmac_set_multicast, n_addrs=%d\n", num_addrs) ;
 
 	if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
 		for (i=0; i<4; i++) bp->hash_table_mask[i] = 0xffff;
 		bmac_update_hash_table_mask(dev, bp);
 		rx_cfg = bmac_rx_on(dev, 1, 0);
-		XXDEBUG(("bmac: all multi, rx_cfg=%#08x\n"));
+		XXDEBUG ("bmac: all multi, rx_cfg=%#08x\n") ;
 	} else if ((dev->flags & IFF_PROMISC) || (num_addrs < 0)) {
 		rx_cfg = bmread(dev, RXCFG);
 		rx_cfg |= RxPromiscEnable;
 		bmwrite(dev, RXCFG, rx_cfg);
 		rx_cfg = bmac_rx_on(dev, 0, 1);
-		XXDEBUG(("bmac: promisc mode enabled, rx_cfg=%#08x\n", rx_cfg));
+		XXDEBUG ("bmac: promisc mode enabled, rx_cfg=%#08x\n", rx_cfg) ;
 	} else {
 		for (i=0; i<4; i++) bp->hash_table_mask[i] = 0;
 		for (i=0; i<64; i++) bp->hash_use_count[i] = 0;
 		if (num_addrs == 0) {
 			rx_cfg = bmac_rx_on(dev, 0, 0);
-			XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg));
+			XXDEBUG ("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg) ;
 		} else {
 			for (dmi=dev->mc_list; dmi!=NULL; dmi=dmi->next)
 				bmac_addhash(bp, dmi->dmi_addr);
 			bmac_update_hash_table_mask(dev, bp);
 			rx_cfg = bmac_rx_on(dev, 1, 0);
-			XXDEBUG(("bmac: multi enabled, rx_cfg=%#08x\n", rx_cfg));
+			XXDEBUG ("bmac: multi enabled, rx_cfg=%#08x\n", rx_cfg) ;
 		}
 	}
-	/* XXDEBUG(("bmac: exit bmac_set_multicast\n")); */
+	XXDEBUG ("bmac: exit bmac_set_multicast\n") ;
 }
 #else /* ifdef SUNHME_MULTICAST */
 
@@ -1081,9 +1091,9 @@
 	struct bmac_data *bp = (struct bmac_data *)dev->priv;
 	unsigned int status = bmread(dev, STATUS);
 	if (miscintcount++ < 10) {
-		XXDEBUG(("bmac_misc_intr\n"));
+		XXDEBUG ("bmac_misc_intr\n") ;
 	}
-	/* XXDEBUG(("bmac_misc_intr, status=%#08x\n", status)); */
+	XXDEBUG ("bmac_misc_intr, status=%#08x\n", status) ;
 	/*     bmac_txdma_intr_inner(irq, dev_id, regs); */
 	/*   if (status & FrameReceived) bp->stats.rx_dropped++; */
 	if (status & RxErrorMask) bp->stats.rx_errors++;
@@ -1096,6 +1106,13 @@
 	if (status & TxErrorMask) bp->stats.tx_errors++;
 	if (status & TxUnderrun) bp->stats.tx_fifo_errors++;
 	if (status & TxNormalCollExp) bp->stats.collisions++;
+
+#ifdef CONFIG_BMAC_NO_STREAM_XMIT_DMA
+	if (status & (FrameSent | TxUnderrun)) {
+		XXDEBUG ("bmac_misc_intr: calling bmac_txdma_intr to restart Xmit DMA!\n");
+		bmac_txdma_intr(irq, dev_id, regs);
+	}
+#endif /* CONFIG_BMAC_NO_STREAM_XMIT_DMA */
 }
 
 /*
@@ -1324,7 +1341,7 @@
 		dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j];
 		printk("%c%.2x", (j? ':': ' '), dev->dev_addr[j]);
 	}
-	XXDEBUG((", base_addr=%#0lx", dev->base_addr));
+	XXDEBUG (", base_addr=%#0lx", dev->base_addr) ;
 	printk("\n");
     
 	dev->open = bmac_open;
@@ -1392,7 +1409,7 @@
 
 static int bmac_open(struct device *dev)
 {
-	/* XXDEBUG(("bmac: enter open\n")); */
+	XXDEBUG ("bmac: enter open\n") ;
 	/* reset the chip */
 	bmac_reset_and_enable(dev, 1);
 
@@ -1426,7 +1443,7 @@
 	st_le32(&td->control, DBDMA_CLEAR(RUN|PAUSE|FLUSH|WAKE));	/* clear run bit */
 
 	/* free some skb's */
-	XXDEBUG(("bmac: free rx bufs\n"));
+	XXDEBUG ("bmac: free rx bufs\n") ;
 	for (i=0; i<N_RX_RING; i++) {
 		if (bp->rx_bufs[i] != NULL) {
 			dev_kfree_skb(bp->rx_bufs[i]);
@@ -1434,7 +1451,7 @@
 		}
 	}
 	bp->rx_allocated = 0;
-	XXDEBUG(("bmac: free tx bufs\n"));
+	XXDEBUG ("bmac: free tx bufs\n") ;
 	for (i = 0; i<N_TX_RING; i++) {
 		if (bp->tx_bufs[i] != NULL) {
 			dev_kfree_skb(bp->tx_bufs[i]);
@@ -1442,7 +1459,7 @@
 		}
 	}
 	bp->reset_and_enabled = 0;
-	XXDEBUG(("bmac: all bufs freed\n"));
+	XXDEBUG ("bmac: all bufs freed\n") ;
 
 	MOD_DEC_USE_COUNT;
 
@@ -1489,7 +1506,7 @@
 	unsigned short config, oldConfig;
 	int i;
 
-	XXDEBUG(("bmac: tx_timeout called\n"));
+	XXDEBUG ("bmac: tx_timeout called\n") ;
 	save_flags(flags); cli();
 	bp->timeout_active = 0;
 
@@ -1497,9 +1514,9 @@
 /*     	bmac_handle_misc_intrs(bp, 0); */
 
 	cp = &bp->tx_cmds[bp->tx_empty];
-/*	XXDEBUG((KERN_DEBUG "bmac: tx dmastat=%x %x runt=%d pr=%x fs=%x fc=%x\n", */
-/* 	   ld_le32(&td->status), ld_le16(&cp->xfer_status), bp->tx_bad_runt, */
-/* 	   mb->pr, mb->xmtfs, mb->fifofc)); */
+	/* XXDEBUG (KERN_DEBUG "bmac: tx dmastat=%x %x runt=%d pr=%x fs=%x fc=%x\n", */
+ 	/*    ld_le32(&td->status), ld_le16(&cp->xfer_status), bp->tx_bad_runt, */
+ 	/*    mb->pr, mb->xmtfs, mb->fifofc) ; */
 
 	/* turn off both tx and rx and reset the chip */
 	config = bmread(dev, RXCFG);
@@ -1518,8 +1535,8 @@
 	out_le32(&rd->control, DBDMA_SET(RUN|WAKE));
 
 	/* fix up the transmit side */
-	XXDEBUG((KERN_DEBUG "bmac: tx empty=%d fill=%d fullup=%d\n",
-		 bp->tx_empty, bp->tx_fill, bp->tx_fullup));
+	XXDEBUG (KERN_DEBUG "bmac: tx empty=%d fill=%d fullup=%d\n",
+		 bp->tx_empty, bp->tx_fill, bp->tx_fullup) ;
 	i = bp->tx_empty;
 	++bp->stats.tx_errors;
 	if (i != bp->tx_fill) {
@@ -1531,7 +1548,7 @@
 	bp->tx_fullup = 0;
 	dev->tbusy = 0;
 	mark_bh(NET_BH);
-	XXDEBUG((KERN_DEBUG "bmac: clearing tbusy\n"));
+	XXDEBUG (KERN_DEBUG "bmac: clearing tbusy\n") ;
 	if (i != bp->tx_fill) {
 		cp = &bp->tx_cmds[i];
 		out_le16(&cp->xfer_status, 0);
@@ -1539,7 +1556,7 @@
 		out_le32(&td->cmdptr, virt_to_bus(cp));
 		out_le32(&td->control, DBDMA_SET(RUN));
 		/* 	bmac_set_timeout(dev); */
-		XXDEBUG((KERN_DEBUG "bmac: starting %d\n", i));
+		XXDEBUG (KERN_DEBUG "bmac: starting %d\n", i) ;
 	}
 
 	/* turn it back on */

