Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Nov 1999 16:30:44 -0500
From:      John Capo <jc@irbs.com>
To:        freebsd-stable@freebsd.org
Subject:   Patch to Support DLINK Quad 21143
Message-ID:  <19991111163043.26294@irbs.com>

next in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991111163043.26294>