From owner-freebsd-stable Thu Nov 11 13:31: 6 1999 Delivered-To: freebsd-stable@freebsd.org Received: from irbs.irbs.com (irbs.irbs.com [209.36.62.129]) by hub.freebsd.org (Postfix) with ESMTP id 9B1B514D30 for ; Thu, 11 Nov 1999 13:30:45 -0800 (PST) (envelope-from jc@irbs.com) Received: (from jc@localhost) by irbs.irbs.com (8.8.5/8.8.5) id QAA20215; Thu, 11 Nov 1999 16:30:44 -0500 (EST) Message-ID: <19991111163043.26294@irbs.com> Date: Thu, 11 Nov 1999 16:30:44 -0500 From: John Capo To: freebsd-stable@freebsd.org Subject: Patch to Support DLINK Quad 21143 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.89i Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG The -stable de driver can not force the DLINK 570TX link speed or duplex mode. Autonegotiation works for 10Mbs half duplex and for 100Mbs full or half duplex. The patch below allows link speed and duplex mode to be set with ifconfig. 10Mbs full duplex autonegotiation is still broken. This patch is against -stable but the modified routine, tulip_media_set(), is the same in -current. A modified tulip_media_set() follows the patch. It would be nice to know if this patch fixes single port 21143 cards. I am sure that 21143 handling is going to be special case depending on the manufacturer and card type. It will be nice when 8255X quad cards are available at resonable prices. John Capo Index: sys/pci/if_de.c =================================================================== RCS file: /usr/cvs/src/sys/pci/if_de.c,v retrieving revision 1.93.2.3 diff -c -r1.93.2.3 if_de.c *** if_de.c 1999/08/29 16:31:35 1.93.2.3 --- if_de.c 1999/11/11 19:51:15 *************** *** 364,402 **** } TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol); TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata); ! } else if (mi->mi_type == TULIP_MEDIAINFO_MII ! && sc->tulip_probe_state != TULIP_PROBE_INACTIVE) { ! int idx; ! if (sc->tulip_features & TULIP_HAVE_SIAGP) { ! const u_int8_t *dp; ! dp = &sc->tulip_rombuf[mi->mi_reset_offset]; ! for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) { ! DELAY(10); ! TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); } - sc->tulip_phyaddr = mi->mi_phyaddr; - dp = &sc->tulip_rombuf[mi->mi_gpr_offset]; - for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) { - DELAY(10); - TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); - } - } else { - for (idx = 0; idx < mi->mi_reset_length; idx++) { - DELAY(10); - TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]); - } - sc->tulip_phyaddr = mi->mi_phyaddr; - for (idx = 0; idx < mi->mi_gpr_length; idx++) { - DELAY(10); - TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]); - } } if (sc->tulip_flags & TULIP_TRYNWAY) { tulip_mii_autonegotiate(sc, sc->tulip_phyaddr); } else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) { u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL); data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE); sc->tulip_flags &= ~TULIP_DIDNWAY; if (TULIP_IS_MEDIA_FD(media)) data |= PHYCTL_FULL_DUPLEX; if (TULIP_IS_MEDIA_100MB(media)) --- 364,406 ---- } TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol); TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata); ! } else if (mi->mi_type == TULIP_MEDIAINFO_MII) { ! if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE) { ! int idx; ! if (sc->tulip_features & TULIP_HAVE_SIAGP) { ! const u_int8_t *dp; ! dp = &sc->tulip_rombuf[mi->mi_reset_offset]; ! for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) { ! DELAY(10); ! TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); ! } ! sc->tulip_phyaddr = mi->mi_phyaddr; ! dp = &sc->tulip_rombuf[mi->mi_gpr_offset]; ! for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) { ! DELAY(10); ! TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); ! } ! } else { ! for (idx = 0; idx < mi->mi_reset_length; idx++) { ! DELAY(10); ! TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]); ! } ! sc->tulip_phyaddr = mi->mi_phyaddr; ! for (idx = 0; idx < mi->mi_gpr_length; idx++) { ! DELAY(10); ! TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]); ! } } } + if (sc->tulip_flags & TULIP_TRYNWAY) { tulip_mii_autonegotiate(sc, sc->tulip_phyaddr); } else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) { u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL); data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE); sc->tulip_flags &= ~TULIP_DIDNWAY; + TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); + TULIP_CSR_WRITE(sc, csr_sia_tx_rx, 0); if (TULIP_IS_MEDIA_FD(media)) data |= PHYCTL_FULL_DUPLEX; if (TULIP_IS_MEDIA_100MB(media)) ---- tulip_media_set() ---- static void tulip_media_set( tulip_softc_t * const sc, tulip_media_t media) { const tulip_media_info_t *mi = sc->tulip_mediums[media]; if (mi == NULL) return; /* * If we are switching media, make sure we don't think there's * any stale RX activity */ sc->tulip_flags &= ~TULIP_RXACT; if (mi->mi_type == TULIP_MEDIAINFO_SIA) { TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); TULIP_CSR_WRITE(sc, csr_sia_tx_rx, mi->mi_sia_tx_rx); if (sc->tulip_features & TULIP_HAVE_SIAGP) { TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG); DELAY(50); TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG); } else { TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG); } TULIP_CSR_WRITE(sc, csr_sia_connectivity, mi->mi_sia_connectivity); } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) { #define TULIP_GPR_CMDBITS (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL) /* * If the cmdmode bits don't match the currently operating mode, * set the cmdmode appropriately and reset the chip. */ if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) { sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS; sc->tulip_cmdmode |= mi->mi_cmdmode; tulip_reset(sc); } TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit); DELAY(10); TULIP_CSR_WRITE(sc, csr_gp, (u_int8_t) mi->mi_gpdata); } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) { /* * If the cmdmode bits don't match the currently operating mode, * set the cmdmode appropriately and reset the chip. */ if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) { sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS; sc->tulip_cmdmode |= mi->mi_cmdmode; tulip_reset(sc); } TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol); TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata); } else if (mi->mi_type == TULIP_MEDIAINFO_MII) { if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE) { int idx; if (sc->tulip_features & TULIP_HAVE_SIAGP) { const u_int8_t *dp; dp = &sc->tulip_rombuf[mi->mi_reset_offset]; for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) { DELAY(10); TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); } sc->tulip_phyaddr = mi->mi_phyaddr; dp = &sc->tulip_rombuf[mi->mi_gpr_offset]; for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) { DELAY(10); TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16); } } else { for (idx = 0; idx < mi->mi_reset_length; idx++) { DELAY(10); TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]); } sc->tulip_phyaddr = mi->mi_phyaddr; for (idx = 0; idx < mi->mi_gpr_length; idx++) { DELAY(10); TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]); } } } if (sc->tulip_flags & TULIP_TRYNWAY) { tulip_mii_autonegotiate(sc, sc->tulip_phyaddr); } else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) { u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL); data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE); sc->tulip_flags &= ~TULIP_DIDNWAY; TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); TULIP_CSR_WRITE(sc, csr_sia_tx_rx, 0); if (TULIP_IS_MEDIA_FD(media)) data |= PHYCTL_FULL_DUPLEX; if (TULIP_IS_MEDIA_100MB(media)) data |= PHYCTL_SELECT_100MB; tulip_mii_writereg(sc, sc->tulip_phyaddr, PHYREG_CONTROL, data); } } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message