Subject: Re: Trouble with installation
To: None <darshu@hotbot.com>
From: Luoqi Chen <luoqi@watermarkgroup.com>
List: port-macppc
Date: 10/18/1999 14:03:00
> So the chipset is a 21041 but I still want to give the patch a try. Can you send me the patch? Thanks.
> 
> Regards,
> 
> Nizam Sayeed
> 
Sure. The patch is for Jason's new tlp driver, so you might want to give the
stock version a try first. If it still doesn't work for you, apply my patch
and try again. Let me know how it turns out.

-lq

Index: tulip.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/tulip.c,v
retrieving revision 1.21
diff -u -r1.21 tulip.c
--- tulip.c	1999/09/29 18:52:19	1.21
+++ tulip.c	1999/09/30 17:59:36
@@ -574,19 +575,21 @@
 			 * yet.  That could cause a race condition.
 			 * 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 =
+			sc->sc_txdescs[nexttx].td_status = TULIP_DBSW(sc,
+			    (nexttx == firsttx) ? 0 : TDSTAT_OWN);
+			sc->sc_txdescs[nexttx].td_bufaddr1 = TULIP_DBSW(sc,
+			    dmamap->dm_segs[seg].ds_addr);
+			sc->sc_txdescs[nexttx].td_ctl = TULIP_DBSW(sc,
 			    (dmamap->dm_segs[seg].ds_len << TDCTL_SIZE1_SHIFT) |
-			    TDCTL_CH;
+			    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;
+		sc->sc_txdescs[sc->sc_txnext].td_ctl |=
+			TULIP_DBSW(sc, TDCTL_Tx_FS);
+		sc->sc_txdescs[lasttx].td_ctl |=
+			TULIP_DBSW(sc, TDCTL_Tx_LS);
 
 #ifdef TLP_DEBUG
 		if (ifp->if_flags & IFF_DEBUG) {
@@ -650,7 +653,7 @@
 		 * Cause a transmit interrupt to happen on the
 		 * last packet we enqueued.
 		 */
-		sc->sc_txdescs[lasttx].td_ctl |= TDCTL_Tx_IC;
+		sc->sc_txdescs[lasttx].td_ctl |= TULIP_DBSW(sc, TDCTL_Tx_IC);
 		TULIP_CDTXSYNC(sc, lasttx, 1,
 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 
@@ -661,7 +664,7 @@
 		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_DBSW(sc, TDCTL_Tx_IC);
 			TULIP_CDTXSYNC(sc, last_txs->txs_firstdesc, 1,
 			    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 		}
@@ -670,7 +673,7 @@
 		 * The entire packet chain is set up.  Give the
 		 * first descriptor to the chip now.
 		 */
-		sc->sc_txdescs[firsttx].td_status |= TDSTAT_OWN;
+		sc->sc_txdescs[firsttx].td_status |= TULIP_DBSW(sc, TDSTAT_OWN);
 		TULIP_CDTXSYNC(sc, firsttx, 1,
 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 
@@ -846,7 +849,8 @@
 	u_int32_t status, rxstatus, txstatus;
 	int handled = 0, txthresh;
 
-	DPRINTF(sc, ("%s: tlp_intr\n", sc->sc_dev.dv_xname));
+	DPRINTF(sc, ("%s: tlp_intr: sc_flags 0x%08x\n",
+	    sc->sc_dev.dv_xname, sc->sc_flags));
 
 	/*
 	 * If the interface isn't running, the interrupt couldn't
@@ -863,6 +867,9 @@
 		if ((status & sc->sc_inten) == 0)
 			break;
 
+		DPRINTF(sc, ("%s: tlp_intr: status %08x\n",
+			sc->sc_dev.dv_xname, status));
+
 		handled = 1;
 
 		rxstatus = status & sc->sc_rxint_mask;
@@ -879,6 +886,21 @@
 			if (rxstatus & STATUS_RU) {
 				printf("%s: receive ring overrun\n",
 				    sc->sc_dev.dv_xname);
+#ifdef TLP_DEBUG
+				if (ifp->if_flags & IFF_DEBUG) {
+					int i = sc->sc_rxptr;
+					printf("rx descriptor %d: %x\n", i,
+					    TULIP_CDRXADDR(sc, i));
+					printf("\td_status:   0x%08x\n",
+					    sc->sc_rxdescs[i].td_status);
+					printf("\td_ctl:      0x%08x\n",
+					    sc->sc_rxdescs[i].td_ctl);
+					printf("\td_bufaddr1: 0x%08x\n",
+					    sc->sc_rxdescs[i].td_bufaddr1);
+					printf("\td_bufaddr2: 0x%08x\n",
+					    sc->sc_rxdescs[i].td_bufaddr2);
+				}
+#endif
 				/* Get the receive process going again. */
 				tlp_idle(sc, OPMODE_SR);
 				TULIP_WRITE(sc, CSR_RXLIST,
@@ -1004,13 +1026,16 @@
 	u_int32_t rxstat;
 	int i, len;
 
+	DPRINTF(sc, ("%s: tlp_rxintr: sc_flags 0x%08x\n",
+	    sc->sc_dev.dv_xname, sc->sc_flags));
+
 	for (i = sc->sc_rxptr;; i = TULIP_NEXTRX(i)) {
 		rxs = &sc->sc_rxsoft[i];
 
 		TULIP_CDRXSYNC(sc, i,
 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 
-		rxstat = sc->sc_rxdescs[i].td_status;
+		rxstat = TULIP_DBSW(sc, sc->sc_rxdescs[i].td_status);
 
 		if (rxstat & TDSTAT_OWN) {
 			/*
@@ -1181,8 +1206,13 @@
 	 */
 	if (sc->sc_flags & TULIPF_DOING_SETUP) {
 		TULIP_CDSDSYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-		if ((sc->sc_setup_desc.td_status & TDSTAT_OWN) == 0)
+		txstat = TULIP_DBSW(sc, sc->sc_setup_desc.td_status);
+		if ((txstat & TDSTAT_OWN) == 0) {
 			sc->sc_flags &= ~TULIPF_DOING_SETUP;
+			/* restart the reception process */
+			sc->sc_opmode |= OPMODE_SR;
+			TULIP_WRITE(sc, CSR_OPMODE, sc->sc_opmode);
+		}
 	}
 
 	/*
@@ -1214,7 +1244,8 @@
 		}
 #endif
 
-		txstat = sc->sc_txdescs[txs->txs_firstdesc].td_status;
+		txstat = TULIP_DBSW(sc,
+		    sc->sc_txdescs[txs->txs_firstdesc].td_status);
 		if (txstat & TDSTAT_OWN)
 			break;
 
@@ -1321,6 +1352,12 @@
 	struct tulip_rxsoft *rxs;
 	int i, error = 0;
 
+	DPRINTF(sc, ("%s: tlp_init: sc_flags 0x%08x\n",
+	    sc->sc_dev.dv_xname, sc->sc_flags));
+
+	if (sc->sc_flags & TULIPF_DOING_SETUP)
+		return (0);
+
 	/*
 	 * Cancel any pending I/O.
 	 */
@@ -1381,7 +1418,11 @@
 	 * 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;
+	TULIP_WRITE(sc, CSR_BUSMODE, 0);
+	if (TULIP_READ(sc, CSR_BUSMODE) & BUSMODE_DBO)
+		sc->sc_flags |= TULIPF_DBO_NA;
+	else
+		sc->sc_busmode |= BUSMODE_DBO;
 #endif
 	TULIP_WRITE(sc, CSR_BUSMODE, sc->sc_busmode);
 
@@ -1420,9 +1461,9 @@
 	 */
 	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_ctl = TULIP_DBSW(sc, TDCTL_CH);
 		sc->sc_txdescs[i].td_bufaddr2 =
-		    TULIP_CDTXADDR(sc, TULIP_NEXTTX(i));
+		    TULIP_DBSW(sc, TULIP_CDTXADDR(sc, TULIP_NEXTTX(i)));
 	}
 	TULIP_CDTXSYNC(sc, 0, TULIP_NTXDESC,
 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@@ -1547,10 +1588,12 @@
 	 */
 	(void) (*sc->sc_mediasw->tmsw_set)(sc);
 
+#if 0
 	/*
 	 * Start the receive process.
 	 */
 	TULIP_WRITE(sc, CSR_RXPOLL, RXPOLL_RPD);
+#endif
 
 	if (sc->sc_tick != NULL) {
 		/* Start the one second clock. */
@@ -2077,13 +2120,15 @@
 		}
 	}
 
-	sc->sc_opmode &= ~(OPMODE_PR|OPMODE_PM);
+	sc->sc_opmode &= ~(OPMODE_PR|OPMODE_PM|OPMODE_SR);
 
 	if (ifp->if_flags & IFF_PROMISC) {
 		sc->sc_opmode |= OPMODE_PR;
 		goto allmulti;
 	}
 
+#define	SYMMETRIC(x, y)	((x) | (y) << 8 | (y) << 16 | (x) << 24)
+
 	/*
 	 * Try Perfect filtering first.
 	 */
@@ -2113,25 +2158,25 @@
 			 */
 			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];
+		*sp++ = SYMMETRIC(enm->enm_addrlo[0], enm->enm_addrlo[1]);
+		*sp++ = SYMMETRIC(enm->enm_addrlo[2], enm->enm_addrlo[3]);
+		*sp++ = SYMMETRIC(enm->enm_addrlo[4], enm->enm_addrlo[5]);
 		ETHER_NEXT_MULTI(step, enm);
 	}
 	
 	if (ifp->if_flags & IFF_BROADCAST) {
 		/* ...and the broadcast address. */
 		cnt++;
-		*sp++ = 0xffff;
-		*sp++ = 0xffff;
-		*sp++ = 0xffff;
+		*sp++ = 0xffffffff;
+		*sp++ = 0xffffffff;
+		*sp++ = 0xffffffff;
 	}
 
 	/* 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];
+		*sp++ = SYMMETRIC(enaddr[0], enaddr[1]);
+		*sp++ = SYMMETRIC(enaddr[2], enaddr[3]);
+		*sp++ = SYMMETRIC(enaddr[4], enaddr[5]);
 	}
 	ifp->if_flags &= ~IFF_ALLMULTI;
 	goto setit;
@@ -2166,28 +2211,31 @@
 			goto allmulti;
 		}
 		hash = tlp_mchash(enm->enm_addrlo);
-		sp[hash >> 4] |= 1 << (hash & 0xf);
+		sp[hash >> 4] |= (1 << (hash & 0xf)) |
+				 bswap32(1 << (hash & 0xf));
 		ETHER_NEXT_MULTI(step, enm);
 	}
 
 	if (ifp->if_flags & IFF_BROADCAST) {
 		/* ...and the broadcast address. */
 		hash = tlp_mchash(etherbroadcastaddr);
-		sp[hash >> 4] |= 1 << (hash & 0xf);
+		sp[hash >> 4] |= (1 << (hash & 0xf)) |
+				 bswap32(1 << (hash & 0xf));
 	}
 
 	if (sc->sc_filtmode == TDCTL_Tx_FT_HASHONLY) {
 		/* ...and our station address. */
 		hash = tlp_mchash(enaddr);
-		sp[hash >> 4] |= 1 << (hash & 0xf);
+		sp[hash >> 4] |= (1 << (hash & 0xf)) |
+				 bswap32(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];
+		sp[39] = SYMMETRIC(enaddr[0], enaddr[1]);
+		sp[40] = SYMMETRIC(enaddr[2], enaddr[3]);
+		sp[41] = SYMMETRIC(enaddr[4], enaddr[5]);
 	}
 	ifp->if_flags &= ~IFF_ALLMULTI;
 	goto setit;
@@ -2204,17 +2252,19 @@
 	cnt = 0;
 	if (ifp->if_flags & IFF_BROADCAST) {
 		cnt++;
-		*sp++ = 0xffff;
-		*sp++ = 0xffff;
-		*sp++ = 0xffff;
+		*sp++ = 0xffffffff;
+		*sp++ = 0xffffffff;
+		*sp++ = 0xffffffff;
 	}
 	for (; cnt < TULIP_MAXADDRS; cnt++) {
-		*sp++ = ((u_int16_t *) enaddr)[0];
-		*sp++ = ((u_int16_t *) enaddr)[1];
-		*sp++ = ((u_int16_t *) enaddr)[2];
+		*sp++ = SYMMETRIC(enaddr[0], enaddr[1]);
+		*sp++ = SYMMETRIC(enaddr[2], enaddr[3]);
+		*sp++ = SYMMETRIC(enaddr[4], enaddr[5]);
 	}
 	ifp->if_flags |= IFF_ALLMULTI;
 
+#undef	SYMMETRIC
+
  setit:
 	if (ifp->if_flags & IFF_ALLMULTI)
 		sc->sc_opmode |= OPMODE_PM;
@@ -2225,13 +2275,14 @@
 	/*
 	 * 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 =
+	sc->sc_setup_desc.td_bufaddr1 = TULIP_DBSW(sc, TULIP_CDSPADDR(sc));
+	sc->sc_setup_desc.td_bufaddr2 =
+	    TULIP_DBSW(sc, TULIP_CDTXADDR(sc, sc->sc_txnext));
+	sc->sc_setup_desc.td_ctl = TULIP_DBSW(sc,
 	    (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;
+	    TDCTL_Tx_IC | TDCTL_CH);
+	sc->sc_setup_desc.td_status = TULIP_DBSW(sc, TDSTAT_OWN);
 	TULIP_CDSDSYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 
 	/*
Index: tulipvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/tulipvar.h,v
retrieving revision 1.16
diff -u -r1.16 tulipvar.h
--- tulipvar.h	1999/09/29 18:52:19	1.16
+++ tulipvar.h	1999/09/30 17:59:37
@@ -348,7 +348,15 @@
 #define	TULIPF_IC_FS		0x00000008	/* IC bit on first tx seg */
 #define	TULIPF_LINK_UP		0x00000010	/* link is up (non-MII) */
 #define	TULIPF_DOINGAUTO	0x00000020	/* doing autoneg (non-MII) */
+#define	TULIPF_DBO_NA		0x00000040	/* DBO bit not available */
 
+/* byte-swap descriptor */
+#if BYTE_ORDER == BIG_ENDIAN
+#define	TULIP_DBSW(sc, x) (((sc)->sc_flags & TULIPF_DBO_NA) ? bswap32(x) : (x))
+#else
+#define	TULIP_DBSW(sc, x) (x)
+#endif
+
 #define	TULIP_CDTXADDR(sc, x)	((sc)->sc_cddma + TULIP_CDTXOFF((x)))
 #define	TULIP_CDRXADDR(sc, x)	((sc)->sc_cddma + TULIP_CDRXOFF((x)))
 
@@ -400,13 +408,18 @@
 	struct tulip_rxsoft *__rxs = &sc->sc_rxsoft[(x)];		\
 	struct tulip_desc *__rxd = &sc->sc_rxdescs[(x)];		\
 	struct mbuf *__m = __rxs->rxs_mbuf;				\
+	u_int32_t __size = (TDCTL_SIZE1 >> TDCTL_SIZE1_SHIFT) & ~3;	\
 									\
 	__m->m_data = __m->m_ext.ext_buf;				\
-	__rxd->td_bufaddr1 = __rxs->rxs_dmamap->dm_segs[0].ds_addr;	\
-	__rxd->td_bufaddr2 = TULIP_CDRXADDR((sc), TULIP_NEXTRX((x)));	\
+	__size = min(__size, __m->m_ext.ext_size);			\
+	__rxd->td_bufaddr1 =						\
+	    TULIP_DBSW((sc), __rxs->rxs_dmamap->dm_segs[0].ds_addr);	\
+	__rxd->td_bufaddr2 =						\
+	    TULIP_DBSW((sc), TULIP_CDRXADDR((sc), TULIP_NEXTRX(x)));	\
 	__rxd->td_ctl =							\
-	    ((__m->m_ext.ext_size - 1) << TDCTL_SIZE1_SHIFT) | TDCTL_CH; \
-	__rxd->td_status = TDSTAT_OWN|TDSTAT_Rx_FS|TDSTAT_Rx_LS;	\
+	    TULIP_DBSW((sc), (__size << TDCTL_SIZE1_SHIFT) | TDCTL_CH);	\
+	__rxd->td_status =						\
+	    TULIP_DBSW((sc), TDSTAT_OWN|TDSTAT_Rx_FS|TDSTAT_Rx_LS);	\
 	TULIP_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
 } while (0)