Subject: Re: 19991204 snapshot.
To: None <mjreilly@flashcom.net>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-macppc
Date: 12/10/1999 16:15:27
On Fri, 10 Dec 1999 18:59:28 -0500 
 Matthew Reilly <mjreilly@flashcom.net> wrote:

 > Jason, I  in no way meant to impugn the quality of your driver. I meant
 > ready for use on a PPC machine. If you need anyone to help with the
 > testing of the driver on a big endian machine I'd be happy to help out.
 > I've got netbsd MacPPC current running and compiling on my SuperMac C500
 > (603e@200Mhz). It's the least I, as a nonprogrammer, can do to help out
 > the people who make open software possible. Again, aything I can do I will.

Please try the following patch and let me know how it goes.  Should
do the trick.

        -- Jason R. Thorpe <thorpej@nas.nasa.gov>

Index: cardbus/if_tlp_cardbus.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/cardbus/if_tlp_cardbus.c,v
retrieving revision 1.4
diff -c -r1.4 if_tlp_cardbus.c
*** if_tlp_cardbus.c	1999/12/07 07:36:19	1.4
--- if_tlp_cardbus.c	1999/12/11 00:11:14
***************
*** 60,65 ****
--- 60,67 ----
  #include <sys/ioctl.h>
  #include <sys/errno.h>
  #include <sys/device.h>
+ 
+ #include <machine/endian.h>
   
  #include <net/if.h>
  #include <net/if_dl.h>
Index: eisa/if_tlp_eisa.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/eisa/if_tlp_eisa.c,v
retrieving revision 1.3
diff -c -r1.3 if_tlp_eisa.c
*** if_tlp_eisa.c	1999/11/19 18:22:42	1.3
--- if_tlp_eisa.c	1999/12/11 00:11:14
***************
*** 55,60 ****
--- 55,62 ----
  #include <sys/ioctl.h>
  #include <sys/errno.h>
  #include <sys/device.h>
+ 
+ #include <machine/endian.h>
   
  #include <net/if.h>
  #include <net/if_dl.h>
Index: pci/if_tlp_pci.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/if_tlp_pci.c,v
retrieving revision 1.26
diff -c -r1.26 if_tlp_pci.c
*** if_tlp_pci.c	1999/12/07 07:36:20	1.26
--- if_tlp_pci.c	1999/12/11 00:11:17
***************
*** 55,60 ****
--- 55,62 ----
  #include <sys/ioctl.h>
  #include <sys/errno.h>
  #include <sys/device.h>
+ 
+ #include <machine/endian.h>
   
  #include <net/if.h>
  #include <net/if_dl.h>
Index: ic/tulip.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/tulip.c,v
retrieving revision 1.34
diff -c -r1.34 tulip.c
*** tulip.c	1999/12/07 18:24:01	1.34
--- tulip.c	1999/12/11 00:11:24
***************
*** 56,61 ****
--- 56,63 ----
  #include <sys/errno.h>
  #include <sys/device.h>
  
+ #include <machine/endian.h>
+ 
  #include <vm/vm.h>		/* for PAGE_SIZE */
   
  #include <net/if.h>
***************
*** 616,633 ****
  			 * We'll do it below.
  			 */
  			sc->sc_txdescs[nexttx].td_status =
! 			    (nexttx == firsttx) ? 0 : TDSTAT_OWN;
  			sc->sc_txdescs[nexttx].td_bufaddr1 =
! 			    dmamap->dm_segs[seg].ds_addr;
  			sc->sc_txdescs[nexttx].td_ctl =
! 			    (dmamap->dm_segs[seg].ds_len << TDCTL_SIZE1_SHIFT) |
! 			    TDCTL_CH;
  			lasttx = nexttx;
  		}
  
  		/* Set `first segment' and `last segment' appropriately. */
! 		sc->sc_txdescs[sc->sc_txnext].td_ctl |= TDCTL_Tx_FS;
! 		sc->sc_txdescs[lasttx].td_ctl |= TDCTL_Tx_LS;
  
  #ifdef TLP_DEBUG
  		if (ifp->if_flags & IFF_DEBUG) {
--- 618,635 ----
  			 * We'll do it below.
  			 */
  			sc->sc_txdescs[nexttx].td_status =
! 			    (nexttx == firsttx) ? 0 : htole32(TDSTAT_OWN);
  			sc->sc_txdescs[nexttx].td_bufaddr1 =
! 			    htole32(dmamap->dm_segs[seg].ds_addr);
  			sc->sc_txdescs[nexttx].td_ctl =
! 			    htole32((dmamap->dm_segs[seg].ds_len <<
! 			        TDCTL_SIZE1_SHIFT) | TDCTL_CH);
  			lasttx = nexttx;
  		}
  
  		/* Set `first segment' and `last segment' appropriately. */
! 		sc->sc_txdescs[sc->sc_txnext].td_ctl |= htole32(TDCTL_Tx_FS);
! 		sc->sc_txdescs[lasttx].td_ctl |= htole32(TDCTL_Tx_LS);
  
  #ifdef TLP_DEBUG
  		if (ifp->if_flags & IFF_DEBUG) {
***************
*** 635,647 ****
  			for (seg = sc->sc_txnext;; seg = TULIP_NEXTTX(seg)) {
  				printf("     descriptor %d:\n", seg);
  				printf("       td_status:   0x%08x\n",
! 				    sc->sc_txdescs[seg].td_status);
  				printf("       td_ctl:      0x%08x\n",
! 				    sc->sc_txdescs[seg].td_ctl);
  				printf("       td_bufaddr1: 0x%08x\n",
! 				    sc->sc_txdescs[seg].td_bufaddr1);
  				printf("       td_bufaddr2: 0x%08x\n",
! 				    sc->sc_txdescs[seg].td_bufaddr2);
  				if (seg == lasttx)
  					break;
  			}
--- 637,649 ----
  			for (seg = sc->sc_txnext;; seg = TULIP_NEXTTX(seg)) {
  				printf("     descriptor %d:\n", seg);
  				printf("       td_status:   0x%08x\n",
! 				    le32toh(sc->sc_txdescs[seg].td_status));
  				printf("       td_ctl:      0x%08x\n",
! 				    le32toh(sc->sc_txdescs[seg].td_ctl));
  				printf("       td_bufaddr1: 0x%08x\n",
! 				    le32toh(sc->sc_txdescs[seg].td_bufaddr1));
  				printf("       td_bufaddr2: 0x%08x\n",
! 				    le32toh(sc->sc_txdescs[seg].td_bufaddr2));
  				if (seg == lasttx)
  					break;
  			}
***************
*** 691,697 ****
  		 * Cause a transmit interrupt to happen on the
  		 * last packet we enqueued.
  		 */
! 		sc->sc_txdescs[lasttx].td_ctl |= TDCTL_Tx_IC;
  		TULIP_CDTXSYNC(sc, lasttx, 1,
  		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
--- 693,699 ----
  		 * Cause a transmit interrupt to happen on the
  		 * last packet we enqueued.
  		 */
! 		sc->sc_txdescs[lasttx].td_ctl |= htole32(TDCTL_Tx_IC);
  		TULIP_CDTXSYNC(sc, lasttx, 1,
  		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
***************
*** 702,708 ****
  		if ((sc->sc_flags & TULIPF_IC_FS) != 0 &&
  		    last_txs->txs_firstdesc != lasttx) {
  			sc->sc_txdescs[last_txs->txs_firstdesc].td_ctl |=
! 			    TDCTL_Tx_IC;
  			TULIP_CDTXSYNC(sc, last_txs->txs_firstdesc, 1,
  			    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  		}
--- 704,710 ----
  		if ((sc->sc_flags & TULIPF_IC_FS) != 0 &&
  		    last_txs->txs_firstdesc != lasttx) {
  			sc->sc_txdescs[last_txs->txs_firstdesc].td_ctl |=
! 			    htole32(TDCTL_Tx_IC);
  			TULIP_CDTXSYNC(sc, last_txs->txs_firstdesc, 1,
  			    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  		}
***************
*** 711,717 ****
  		 * The entire packet chain is set up.  Give the
  		 * first descriptor to the chip now.
  		 */
! 		sc->sc_txdescs[firsttx].td_status |= TDSTAT_OWN;
  		TULIP_CDTXSYNC(sc, firsttx, 1,
  		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
--- 713,719 ----
  		 * The entire packet chain is set up.  Give the
  		 * first descriptor to the chip now.
  		 */
! 		sc->sc_txdescs[firsttx].td_status |= htole32(TDSTAT_OWN);
  		TULIP_CDTXSYNC(sc, firsttx, 1,
  		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
***************
*** 1055,1061 ****
  		TULIP_CDRXSYNC(sc, i,
  		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  
! 		rxstat = sc->sc_rxdescs[i].td_status;
  
  		if (rxstat & TDSTAT_OWN) {
  			/*
--- 1057,1063 ----
  		TULIP_CDRXSYNC(sc, i,
  		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  
! 		rxstat = le32toh(sc->sc_rxdescs[i].td_status);
  
  		if (rxstat & TDSTAT_OWN) {
  			/*
***************
*** 1246,1265 ****
  			for (i = txs->txs_firstdesc;; i = TULIP_NEXTTX(i)) {
  				printf("     descriptor %d:\n", i);
  				printf("       td_status:   0x%08x\n",
! 				    sc->sc_txdescs[i].td_status);
  				printf("       td_ctl:      0x%08x\n",
! 				    sc->sc_txdescs[i].td_ctl);
  				printf("       td_bufaddr1: 0x%08x\n",
! 				    sc->sc_txdescs[i].td_bufaddr1);
  				printf("       td_bufaddr2: 0x%08x\n",
! 				    sc->sc_txdescs[i].td_bufaddr2);
  				if (i == txs->txs_lastdesc)
  					break;
  			}
  		}
  #endif
  
! 		txstat = sc->sc_txdescs[txs->txs_lastdesc].td_status;
  		if (txstat & TDSTAT_OWN)
  			break;
  
--- 1248,1267 ----
  			for (i = txs->txs_firstdesc;; i = TULIP_NEXTTX(i)) {
  				printf("     descriptor %d:\n", i);
  				printf("       td_status:   0x%08x\n",
! 				    le32toh(sc->sc_txdescs[i].td_status));
  				printf("       td_ctl:      0x%08x\n",
! 				    le32toh(sc->sc_txdescs[i].td_ctl));
  				printf("       td_bufaddr1: 0x%08x\n",
! 				    le32toh(sc->sc_txdescs[i].td_bufaddr1));
  				printf("       td_bufaddr2: 0x%08x\n",
! 				    le32toh(sc->sc_txdescs[i].td_bufaddr2));
  				if (i == txs->txs_lastdesc)
  					break;
  			}
  		}
  #endif
  
! 		txstat = le32toh(sc->sc_txdescs[txs->txs_lastdesc].td_status);
  		if (txstat & TDSTAT_OWN)
  			break;
  
***************
*** 1459,1470 ****
  	}
  #if BYTE_ORDER == BIG_ENDIAN
  	/*
! 	 * XXX There are reports that this doesn't work properly
! 	 * in the old Tulip driver, but BUSMODE_DBO does.  However,
! 	 * BUSMODE_DBO is not available on the 21040, and requires
! 	 * us to byte-swap the setup packet.  What to do?
  	 */
- 	sc->sc_busmode |= BUSMODE_BLE;
  #endif
  	TULIP_WRITE(sc, CSR_BUSMODE, sc->sc_busmode);
  
--- 1461,1470 ----
  	}
  #if BYTE_ORDER == BIG_ENDIAN
  	/*
! 	 * Can't use BUSMODE_BLE or BUSMODE_DBO; not all chips
! 	 * support them, and even on ones that do, it doesn't
! 	 * always work.
  	 */
  #endif
  	TULIP_WRITE(sc, CSR_BUSMODE, sc->sc_busmode);
  
***************
*** 1504,1512 ****
  	 */
  	memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
  	for (i = 0; i < TULIP_NTXDESC; i++) {
! 		sc->sc_txdescs[i].td_ctl = TDCTL_CH;
  		sc->sc_txdescs[i].td_bufaddr2 =
! 		    TULIP_CDTXADDR(sc, TULIP_NEXTTX(i));
  	}
  	TULIP_CDTXSYNC(sc, 0, TULIP_NTXDESC,
  	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
--- 1504,1512 ----
  	 */
  	memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
  	for (i = 0; i < TULIP_NTXDESC; i++) {
! 		sc->sc_txdescs[i].td_ctl = htole32(TDCTL_CH);
  		sc->sc_txdescs[i].td_bufaddr2 =
! 		    htole32(TULIP_CDTXADDR(sc, TULIP_NEXTTX(i)));
  	}
  	TULIP_CDTXSYNC(sc, 0, TULIP_NTXDESC,
  	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
***************
*** 2220,2244 ****
  			 */
  			goto hashperfect;
  		}
! 		*sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
! 		*sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
! 		*sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
  		ETHER_NEXT_MULTI(step, enm);
  	}
  	
  	if (ifp->if_flags & IFF_BROADCAST) {
  		/* ...and the broadcast address. */
  		cnt++;
! 		*sp++ = 0xffff;
! 		*sp++ = 0xffff;
! 		*sp++ = 0xffff;
  	}
  
  	/* Pad the rest with our station address. */
  	for (; cnt < TULIP_MAXADDRS; cnt++) {
! 		*sp++ = ((u_int16_t *) enaddr)[0];
! 		*sp++ = ((u_int16_t *) enaddr)[1];
! 		*sp++ = ((u_int16_t *) enaddr)[2];
  	}
  	ifp->if_flags &= ~IFF_ALLMULTI;
  	goto setit;
--- 2220,2244 ----
  			 */
  			goto hashperfect;
  		}
! 		*sp++ = TULIP_SP_FIELD(enm->enm_addrlo, 0);
! 		*sp++ = TULIP_SP_FIELD(enm->enm_addrlo, 1);
! 		*sp++ = TULIP_SP_FIELD(enm->enm_addrlo, 2);
  		ETHER_NEXT_MULTI(step, enm);
  	}
  	
  	if (ifp->if_flags & IFF_BROADCAST) {
  		/* ...and the broadcast address. */
  		cnt++;
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
  	}
  
  	/* Pad the rest with our station address. */
  	for (; cnt < TULIP_MAXADDRS; cnt++) {
! 		*sp++ = TULIP_SP_FIELD(enaddr, 0);
! 		*sp++ = TULIP_SP_FIELD(enaddr, 1);
! 		*sp++ = TULIP_SP_FIELD(enaddr, 2);
  	}
  	ifp->if_flags &= ~IFF_ALLMULTI;
  	goto setit;
***************
*** 2273,2300 ****
  			goto allmulti;
  		}
  		hash = tlp_mchash(enm->enm_addrlo, hashsize);
! 		sp[hash >> 4] |= 1 << (hash & 0xf);
  		ETHER_NEXT_MULTI(step, enm);
  	}
  
  	if (ifp->if_flags & IFF_BROADCAST) {
  		/* ...and the broadcast address. */
  		hash = tlp_mchash(etherbroadcastaddr, hashsize);
! 		sp[hash >> 4] |= 1 << (hash & 0xf);
  	}
  
  	if (sc->sc_filtmode == TDCTL_Tx_FT_HASHONLY) {
  		/* ...and our station address. */
  		hash = tlp_mchash(enaddr, hashsize);
! 		sp[hash >> 4] |= 1 << (hash & 0xf);
  	} else {
  		/*
  		 * Hash-Perfect mode; put our station address after
  		 * the hash table.
  		 */
! 		sp[39] = ((u_int16_t *) enaddr)[0];
! 		sp[40] = ((u_int16_t *) enaddr)[1];
! 		sp[41] = ((u_int16_t *) enaddr)[2];
  	}
  	ifp->if_flags &= ~IFF_ALLMULTI;
  	goto setit;
--- 2273,2300 ----
  			goto allmulti;
  		}
  		hash = tlp_mchash(enm->enm_addrlo, hashsize);
! 		sp[hash >> 4] |= htole32(1 << (hash & 0xf));
  		ETHER_NEXT_MULTI(step, enm);
  	}
  
  	if (ifp->if_flags & IFF_BROADCAST) {
  		/* ...and the broadcast address. */
  		hash = tlp_mchash(etherbroadcastaddr, hashsize);
! 		sp[hash >> 4] |= htole32(1 << (hash & 0xf));
  	}
  
  	if (sc->sc_filtmode == TDCTL_Tx_FT_HASHONLY) {
  		/* ...and our station address. */
  		hash = tlp_mchash(enaddr, hashsize);
! 		sp[hash >> 4] |= htole32(1 << (hash & 0xf));
  	} else {
  		/*
  		 * Hash-Perfect mode; put our station address after
  		 * the hash table.
  		 */
! 		sp[39] = TULIP_SP_FIELD(enaddr, 0);
! 		sp[40] = TULIP_SP_FIELD(enaddr, 1);
! 		sp[41] = TULIP_SP_FIELD(enaddr, 2);
  	}
  	ifp->if_flags &= ~IFF_ALLMULTI;
  	goto setit;
***************
*** 2311,2324 ****
  	cnt = 0;
  	if (ifp->if_flags & IFF_BROADCAST) {
  		cnt++;
! 		*sp++ = 0xffff;
! 		*sp++ = 0xffff;
! 		*sp++ = 0xffff;
  	}
  	for (; cnt < TULIP_MAXADDRS; cnt++) {
! 		*sp++ = ((u_int16_t *) enaddr)[0];
! 		*sp++ = ((u_int16_t *) enaddr)[1];
! 		*sp++ = ((u_int16_t *) enaddr)[2];
  	}
  	ifp->if_flags |= IFF_ALLMULTI;
  
--- 2311,2324 ----
  	cnt = 0;
  	if (ifp->if_flags & IFF_BROADCAST) {
  		cnt++;
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
! 		*sp++ = TULIP_SP_FIELD_C(0xffff);
  	}
  	for (; cnt < TULIP_MAXADDRS; cnt++) {
! 		*sp++ = TULIP_SP_FIELD(enaddr, 0);
! 		*sp++ = TULIP_SP_FIELD(enaddr, 1);
! 		*sp++ = TULIP_SP_FIELD(enaddr, 2);
  	}
  	ifp->if_flags |= IFF_ALLMULTI;
  
***************
*** 2332,2344 ****
  	/*
  	 * Fill in the setup packet descriptor.
  	 */
! 	sc->sc_setup_desc.td_bufaddr1 = TULIP_CDSPADDR(sc);
! 	sc->sc_setup_desc.td_bufaddr2 = TULIP_CDTXADDR(sc, sc->sc_txnext);
  	sc->sc_setup_desc.td_ctl =
! 	    (TULIP_SETUP_PACKET_LEN << TDCTL_SIZE1_SHIFT) |
  	    sc->sc_filtmode | TDCTL_Tx_SET | TDCTL_Tx_FS | TDCTL_Tx_LS |
! 	    TDCTL_Tx_IC | TDCTL_CH;
! 	sc->sc_setup_desc.td_status = TDSTAT_OWN;
  	TULIP_CDSDSYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
  	/*
--- 2332,2345 ----
  	/*
  	 * Fill in the setup packet descriptor.
  	 */
! 	sc->sc_setup_desc.td_bufaddr1 = htole32(TULIP_CDSPADDR(sc));
! 	sc->sc_setup_desc.td_bufaddr2 =
! 	    htole32(TULIP_CDTXADDR(sc, sc->sc_txnext));
  	sc->sc_setup_desc.td_ctl =
! 	    htole32((TULIP_SETUP_PACKET_LEN << TDCTL_SIZE1_SHIFT) |
  	    sc->sc_filtmode | TDCTL_Tx_SET | TDCTL_Tx_FS | TDCTL_Tx_LS |
! 	    TDCTL_Tx_IC | TDCTL_CH);
! 	sc->sc_setup_desc.td_status = htole32(TDSTAT_OWN);
  	TULIP_CDSDSYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  
  	/*
Index: ic/tulipvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/tulipvar.h,v
retrieving revision 1.21
diff -c -r1.21 tulipvar.h
*** tulipvar.h	1999/11/19 18:22:43	1.21
--- tulipvar.h	1999/12/11 00:11:24
***************
*** 476,481 ****
--- 476,488 ----
  #define	TULIP_ISSET(sc, reg, mask)					\
  	(TULIP_READ((sc), (reg)) & (mask))
  
+ #if BYTE_ORDER == BIG_ENDIAN
+ #define	TULIP_SP_FIELD_C(x)	((x) << 16)
+ #else
+ #define	TULIP_SP_FIELD_C(x)	(x)
+ #endif
+ #define	TULIP_SP_FIELD(x, f)	TULIP_SP_FIELD_C(((u_int16_t *)(x))[(f)])
+ 
  #ifdef _KERNEL
  extern const struct tulip_mediasw tlp_21040_mediasw;
  extern const struct tulip_mediasw tlp_21040_tp_mediasw;