From owner-freebsd-bugs Mon Feb 9 18:20:07 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id SAA19202 for freebsd-bugs-outgoing; Mon, 9 Feb 1998 18:20:07 -0800 (PST) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id SAA19191; Mon, 9 Feb 1998 18:20:04 -0800 (PST) (envelope-from gnats) Received: from hardrock.sdsmt.edu (cisco097.sdsmt.edu [151.159.97.254] (may be forged)) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id SAA18576 for ; Mon, 9 Feb 1998 18:17:14 -0800 (PST) (envelope-from sbauer@hardrock.sdsmt.edu) Received: (from sbauer@localhost) by hardrock.sdsmt.edu (8.8.8/8.8.8) id TAA00487; Mon, 9 Feb 1998 19:17:12 -0700 (MST) (envelope-from sbauer) Message-Id: <199802100217.TAA00487@hardrock.sdsmt.edu> Date: Mon, 9 Feb 1998 19:17:12 -0700 (MST) From: Steve Bauer Reply-To: sbauer@hardrock.sdsmt.edu To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: kern/5694: patch to remove DELAY(300000) from if_tx.c driver Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 5694 >Category: kern >Synopsis: Remove DELAY(300000) from if_tx.c driver (SMC9432) >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Feb 9 18:20:02 PST 1998 >Last-Modified: >Originator: Steve Bauer >Organization: South Dakota School of Mines and Technology >Release: FreeBSD 3.0-CURRENT i386 >Environment: FreeBSD 3.0-Current i386 as of 7pm MST on 2/9/98 Running On a Gateway NS7000 2 processor smp machine. >Description: In the auto-negotiation function there was a DELAY(300000) which needed to be removed if possible. With the following patch, the DELAY was removed from the sequence thus speeding up the testing of the different speeds. There are also a few other changes in how the driver reset some interrupt status bits -- It was missing the case where RQE was turned off. >How-To-Repeat: Start auto-negotiation and it would pause the machine for about 3 seconds. >Fix: *** if_tx.c Sun Feb 8 23:10:53 1998 --- if_tx.c.new Mon Feb 9 19:07:39 1998 *************** *** 107,112 **** --- 107,113 ---- &epic_pci_count, NULL }; + static void epic_shutdown __P((int, void *)); /* * Append this driver to pci drivers list */ *************** *** 243,249 **** } /* Does not generate TXC unless ring is full more then a half */ ! buf->desc.control = (sc->pending_txs>TX_RING_SIZE/2)?0x14:0x10; #endif --- 244,250 ---- } /* Does not generate TXC unless ring is full more then a half */ ! buf->desc.control = (sc->pending_txs>TX_RING_SIZE/2)?0x14:0x10; #endif *************** *** 327,345 **** epic_rx_done( sc ); outl( iobase + INTSTAT, status & (INTSTAT_RQE|INTSTAT_HCC|INTSTAT_RCC) ); } - - if( status & (INTSTAT_TXC|INTSTAT_TCC) ) { - epic_tx_done( sc ); - outl( iobase + INTSTAT, - status & (INTSTAT_TXC|INTSTAT_TCC) ); - } - if( (status & INTSTAT_TQE) && !(sc->epic_if.if_flags & IFF_OACTIVE) ) { epic_ifstart( &sc->epic_if ); outl( iobase + INTSTAT, INTSTAT_TQE ); } #if 0 if( status & INTSTAT_GP2 ){ printf("tx%d: GP2 int occured\n",sc->unit); --- 328,347 ---- epic_rx_done( sc ); outl( iobase + INTSTAT, status & (INTSTAT_RQE|INTSTAT_HCC|INTSTAT_RCC) ); + /*if INTSTAT_RQE then RXQUEUED needs to be reset*/ + outl( iobase + COMMAND, COMMAND_RXQUEUED); } if( (status & INTSTAT_TQE) && !(sc->epic_if.if_flags & IFF_OACTIVE) ) { epic_ifstart( &sc->epic_if ); outl( iobase + INTSTAT, INTSTAT_TQE ); } + if( status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE) ) { + epic_tx_done( sc ); + outl( iobase + INTSTAT, + status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE) ); + } + #if 0 if( status & INTSTAT_GP2 ){ printf("tx%d: GP2 int occured\n",sc->unit); *************** *** 781,786 **** --- 783,789 ---- if( !(i & BMSR_LINK_STATUS) ) printf("tx%d: WARNING! no link estabilished\n",sc->unit); + at_shutdown(epic_shutdown, sc, SHUTDOWN_POST_SYNC); /* * Attach to if manager */ *************** *** 814,821 **** /* Soft reset the chip. */ outl(iobase + GENCTL, GENCTL_SOFT_RESET ); ! /* Reset takes 15 ticks */ ! for(i=0;i<0x100;i++); /* Wake up */ outl( iobase + GENCTL, 0 ); --- 817,824 ---- /* Soft reset the chip. */ outl(iobase + GENCTL, GENCTL_SOFT_RESET ); ! /* Reset takes 15 pci ticks which depends on processor speed*/ ! DELAY(1); /* Wake up */ outl( iobase + GENCTL, 0 ); *************** *** 970,1042 **** * This is the recommended time from the DP83840A data sheet * Section 7.1 */ - DELAY(3000000); epic_read_phy_register( sc->iobase, DP83840_BMSR); - - /* BMSR must be read twice to update the link status bit/ - * since that bit is a latch bit - */ i = epic_read_phy_register( sc->iobase, DP83840_BMSR); ! ! if ((i & BMSR_LINK_STATUS) && ( i & BMSR_AUTONEG_COMPLETE)){ ! i = epic_read_phy_register( sc->iobase, DP83840_PAR); ! ! if ( i & PAR_FULL_DUPLEX ) ! return EPIC_FULL_DUPLEX; ! else ! return EPIC_HALF_DUPLEX; ! } ! else { /*Auto-negotiation or link status is not 1 ! Thus the auto-negotiation failed and one ! must take other means to fix it. ! */ ! ! /* ANER must be read twice to get the correct reading for the ! * Multiple link fault bit -- it is a latched bit ! */ ! epic_read_phy_register (sc->iobase, DP83840_ANER); ! i = epic_read_phy_register (sc->iobase, DP83840_ANER); ! ! if ( i & ANER_MULTIPLE_LINK_FAULT ) { ! /* it can be forced to 100Mb/s Half-Duplex */ ! media = epic_read_phy_register(sc->iobase,DP83840_BMCR); ! media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX); ! media |= BMCR_100MBPS; ! epic_write_phy_register(sc->iobase,DP83840_BMCR,media); ! ! /* read BMSR again to determine link status */ ! epic_read_phy_register(sc->iobase, DP83840_BMSR); ! i=epic_read_phy_register( sc->iobase, DP83840_BMSR); ! ! if (i & BMSR_LINK_STATUS){ ! /* port is linked to the non Auto-Negotiation ! * 100Mbs partner. ! */ ! return EPIC_HALF_DUPLEX; } else { ! media = epic_read_phy_register (sc->iobase, DP83840_BMCR); ! media &= !(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX | BMCR_100MBPS); ! epic_write_phy_register(sc->iobase, DP83840_BMCR, media); epic_read_phy_register(sc->iobase, DP83840_BMSR); i=epic_read_phy_register( sc->iobase, DP83840_BMSR); ! ! if (i & BMSR_LINK_STATUS) { ! /*port is linked to the non ! * Auto-Negotiation10Mbs partner ! */ return EPIC_HALF_DUPLEX; } } } ! /* If we get here we are most likely not connected ! * so lets default it to half duplex ! */ ! return EPIC_HALF_DUPLEX; } ! } /* --- 973,1050 ---- * This is the recommended time from the DP83840A data sheet * Section 7.1 */ epic_read_phy_register( sc->iobase, DP83840_BMSR); i = epic_read_phy_register( sc->iobase, DP83840_BMSR); ! for(;;) { ! if ((i & BMSR_LINK_STATUS) && ( i & BMSR_AUTONEG_COMPLETE)){ ! /* Auto negotiation finished!*/ ! i = epic_read_phy_register( sc->iobase, DP83840_PAR); ! if ( i & PAR_FULL_DUPLEX ) { ! return EPIC_FULL_DUPLEX; } else { ! return EPIC_HALF_DUPLEX; ! } ! } ! else { ! /*Auto-negotiation or link status is not 1 ! Thus the auto-negotiation failed and one ! must take other means to fix it. ! */ ! ! /* ANER must be read twice to get the correct reading ! * from theMultiple link fault bit -- it is a latched ! bit ! */ ! epic_read_phy_register (sc->iobase, DP83840_ANER); ! ! i = epic_read_phy_register (sc->iobase, DP83840_ANER); ! ! if ( i & ANER_MULTIPLE_LINK_FAULT ) { ! /* it can be forced to 100Mb/s Half-Duplex */ ! media = epic_read_phy_register(sc->iobase,DP83840_BMCR); ! media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX); ! media |= BMCR_100MBPS; ! epic_write_phy_register(sc->iobase,DP83840_BMCR,media); ! ! /* read BMSR again to determine link status */ epic_read_phy_register(sc->iobase, DP83840_BMSR); i=epic_read_phy_register( sc->iobase, DP83840_BMSR); ! ! if (i & BMSR_LINK_STATUS){ ! /* port is linked to the non ! * Auto-Negotiation 100Mbs partner. ! */ return EPIC_HALF_DUPLEX; } + else { + media = epic_read_phy_register (sc->iobase, DP83840_BMCR); + media &= !(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX | BMCR_100MBPS); + epic_write_phy_register(sc->iobase, DP83840_BMCR, media); + epic_read_phy_register(sc->iobase, DP83840_BMSR); + i=epic_read_phy_register( sc->iobase, DP83840_BMSR); + + if (i & BMSR_LINK_STATUS) { + /*port is linked to the non + * Auto-Negotiation10Mbs partner + */ + return EPIC_HALF_DUPLEX; + } + else { + break; + } + } } } ! epic_read_phy_register( sc->iobase, DP83840_BMSR); ! i = epic_read_phy_register( sc->iobase, DP83840_BMSR); } ! /* If we get here we are most likely not connected ! * so lets default it to half duplex ! */ ! return EPIC_HALF_DUPLEX; } /* *************** *** 1058,1063 **** --- 1066,1079 ---- return; } + static void + epic_shutdown( + int howto, + void *sc) + { + epic_stop(sc); + } + /* * This function should completely stop rx and tx processes * *************** *** 1093,1099 **** /* Reset chip */ outl( iobase + GENCTL, GENCTL_SOFT_RESET ); ! for(i=0;i<0x100;i++); /* Free memory allocated for rings */ epic_free_rings( sc ); --- 1109,1117 ---- /* Reset chip */ outl( iobase + GENCTL, GENCTL_SOFT_RESET ); ! ! /* need to wait for 15 pci ticks to pass before accessing again*/ ! DELAY(1); /* Free memory allocated for rings */ epic_free_rings( sc ); >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message