Date: Mon, 9 Feb 1998 19:17:12 -0700 (MST) From: Steve Bauer <sbauer@hardrock.sdsmt.edu> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/5694: patch to remove DELAY(300000) from if_tx.c driver Message-ID: <199802100217.TAA00487@hardrock.sdsmt.edu>
next in thread | raw e-mail | index | archive | help
>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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802100217.TAA00487>
