Subject: kern/10194: tlp doesn't handle Davicom DM9102
To: None <gnats-bugs@gnats.netbsd.org>
From: IWAMOTO Toshihiro <iwamoto@sat.t.u-tokyo.ac.jp>
List: netbsd-bugs
Date: 05/24/2000 09:12:18
>Number: 10194
>Category: kern
>Synopsis: tlp doesn't handle Davicom DM9102
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed May 24 09:13:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: IWAMOTO Toshihiro
>Release: a week ago -current
>Organization:
>Environment:
System: NetBSD kiku.my.domain 1.4Y NetBSD 1.4Y (KIKU) #8: Wed May 24 22:31:22 JST 2000 toshii@miyuki.my.domain:/usr/src/syssrc/sys/arch/i386/compile/KIKU i386
>Description:
Davicom's DM9102 is a tulip clone Ethernet chip.
This PR adds support for DM9102 as a patch to the tlp driver.
>How-To-Repeat:
Buy a PC with DM9102 but without a PCI slot, and be at a loss.
>Fix:
Apply the following patch.
Although this is basically a trivial patch, it should be noted
that DM9102 can't handle a setup packet if TDCTL_Tx_FS and
TDCTL_Tx_LS bits are set. Intel's 21143 hardware reference
manual says that these bits should be 0 for setup packets.
As this patch unconditionally clears these bits, this patch
should fail with a variant of tulip which requires these bits
to be set (if such tulip clone ever exists).
As a further notice, FreeBSD's "dc" driver (for tulip clones)
unconditionally sets these bits 0.
Index: ic/tulip.c
===================================================================
RCS file: /export/NetBSD-CVS/syssrc/sys/dev/ic/tulip.c,v
retrieving revision 1.64
diff -u -r1.64 tulip.c
--- ic/tulip.c 2000/05/18 03:02:45 1.64
+++ ic/tulip.c 2000/05/24 15:02:24
@@ -146,6 +146,7 @@
void tlp_2114x_preinit __P((struct tulip_softc *));
void tlp_2114x_mii_preinit __P((struct tulip_softc *));
void tlp_pnic_preinit __P((struct tulip_softc *));
+void tlp_dm9102_preinit __P((struct tulip_softc *));
void tlp_21140_reset __P((struct tulip_softc *));
void tlp_21142_reset __P((struct tulip_softc *));
@@ -316,6 +317,11 @@
sc->sc_flags |= TULIPF_IC_FS;
break;
+ case TULIP_CHIP_DM9102:
+ sc->sc_preinit = tlp_dm9102_preinit;
+ sc->sc_tdctl_ch = TDCTL_CH;
+ sc->sc_tdctl_er = 0;
+ break;
default:
/*
* Default to running in ring mode.
@@ -382,9 +388,13 @@
* 4-byte aligned. We're almost guaranteed to have to copy
* the packet in that case, so we just limit ourselves to
* one segment.
+ *
+ * For DM9102, an mbuf chain should be a single mbuf
+ * cluster buffer.
*/
switch (sc->sc_chip) {
case TULIP_CHIP_X3201_3:
+ case TULIP_CHIP_DM9102:
sc->sc_ntxsegs = 1;
break;
@@ -617,6 +627,7 @@
tlp_stop(sc, 1);
}
+
/*
* tlp_start: [ifnet interface function]
*
@@ -777,7 +788,7 @@
#ifdef TLP_DEBUG
if (ifp->if_flags & IFF_DEBUG) {
- printf(" txsoft %p trainsmit chain:\n", txs);
+ printf(" txsoft %p transmit chain:\n", txs);
for (seg = sc->sc_txnext;; seg = TULIP_NEXTTX(seg)) {
printf(" descriptor %d:\n", seg);
printf(" td_status: 0x%08x\n",
@@ -1397,7 +1408,7 @@
#ifdef TLP_DEBUG
if (ifp->if_flags & IFF_DEBUG) {
int i;
- printf(" txsoft %p trainsmit chain:\n", txs);
+ printf(" txsoft %p transmit chain:\n", txs);
for (i = txs->txs_firstdesc;; i = TULIP_NEXTTX(i)) {
printf(" descriptor %d:\n", i);
printf(" td_status: 0x%08x\n",
@@ -1618,6 +1629,9 @@
* Note: We must *always* set these bits; a cache
* alignment of 0 is RESERVED.
*/
+ case 0:
+ sc->sc_busmode |= BUSMODE_CAL_NONE;
+ break;
case 8:
sc->sc_busmode |= BUSMODE_CAL_8LW;
break;
@@ -2643,10 +2657,11 @@
sc->sc_txdescs[sc->sc_txnext].td_bufaddr1 =
htole32(TULIP_CDSPADDR(sc));
+ /* 21143's document says that FS and LS should be cleared */
sc->sc_txdescs[sc->sc_txnext].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 | sc->sc_tdctl_ch |
+ sc->sc_filtmode | TDCTL_Tx_SET |
+ TDCTL_Tx_IC | sc->sc_tdctl_ch |
(sc->sc_txnext == (TULIP_NTXDESC - 1) ? sc->sc_tdctl_er : 0));
sc->sc_txdescs[sc->sc_txnext].td_status = htole32(TDSTAT_OWN);
TULIP_CDTXSYNC(sc, sc->sc_txnext, txs->txs_ndescs,
@@ -3308,6 +3323,14 @@
*/
sc->sc_opmode |= OPMODE_PNIC_TBEN;
}
+}
+
+void
+tlp_dm9102_preinit(sc)
+ struct tulip_softc *sc;
+{
+ sc->sc_opmode |= OPMODE_MBO|OPMODE_HBD;
+ TULIP_WRITE(sc, CSR_OPMODE, sc->sc_opmode);
}
/*
Index: ic/tulipreg.h
===================================================================
RCS file: /export/NetBSD-CVS/syssrc/sys/dev/ic/tulipreg.h,v
retrieving revision 1.18
diff -u -r1.18 tulipreg.h
--- ic/tulipreg.h 2000/04/04 19:22:52 1.18
+++ ic/tulipreg.h 2000/05/24 15:05:39
@@ -547,12 +547,12 @@
#define OPMODE_CA 0x00020000 /* capture effect enable */
#define OPMODE_PNIC_TBEN 0x00020000 /* Tx backoff offset enable */
/*
- * On Davicom DM9102, OPMODE_PS and OPMODE_HBD must
- * always be set.
+ * On Davicom DM9102, OPMODE_HBD must always be set.
*/
#define OPMODE_PS 0x00040000 /* port select:
1 = MII/SYM, 0 = SRL
- (21140) */
+ (21140)
+ 1 = HomePNA (DM9102A) */
#define OPMODE_HBD 0x00080000 /* heartbeat disable:
set in MII/SYM 100mbps,
set according to PHY
Index: pci/if_tlp_pci.c
===================================================================
RCS file: /export/NetBSD-CVS/syssrc/sys/dev/pci/if_tlp_pci.c,v
retrieving revision 1.37
diff -u -r1.37 if_tlp_pci.c
--- pci/if_tlp_pci.c 2000/04/04 19:22:51 1.37
+++ pci/if_tlp_pci.c 2000/05/24 15:05:50
@@ -176,10 +176,8 @@
{ PCI_VENDOR_COMPEX, PCI_PRODUCT_COMPEX_RL100ATX,
TULIP_CHIP_WB89C840F },
-#if 0
{ PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9102,
TULIP_CHIP_DM9102 },
-#endif
{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AL981,
TULIP_CHIP_AL981 },
@@ -526,8 +524,11 @@
/*
* Get the cacheline size.
*/
- sc->sc_cacheline = PCI_CACHELINE(pci_conf_read(pc, pa->pa_tag,
- PCI_BHLC_REG));
+ if (sc->sc_chip == TULIP_CHIP_DM9102)
+ sc->sc_cacheline = 0;
+ else
+ sc->sc_cacheline = PCI_CACHELINE(pci_conf_read(pc, pa->pa_tag,
+ PCI_BHLC_REG));
/*
* Get PCI data moving command info.
@@ -798,6 +799,16 @@
/*
* Winbond 89C840F has an MII attached to the SIO.
*/
+ sc->sc_mediasw = &tlp_sio_mii_mediasw;
+ break;
+
+ case TULIP_CHIP_DM9102:
+ /*
+ * DM9102's Ethernet address is located
+ * at offset 20 of its EEPROM.
+ */
+ memcpy(enaddr, &sc->sc_srom[20], ETHER_ADDR_LEN);
+
sc->sc_mediasw = &tlp_sio_mii_mediasw;
break;
>Release-Note:
>Audit-Trail:
>Unformatted: