Bug 30495 - 3c59x.c uses hard coded countdown timeouts, which are not adequate on 866MHz using 905TXM NIC
Summary: 3c59x.c uses hard coded countdown timeouts, which are not adequate on 866MHz ...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: kernel
Version: 7.0
Hardware: i386
OS: Linux
medium
high
Target Milestone: ---
Assignee: Arjan van de Ven
QA Contact: Brock Organ
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-03-03 23:44 UTC by Need Real Name
Modified: 2007-04-18 16:31 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-06-05 23:55:15 UTC
Embargoed:


Attachments (Terms of Use)

Description Need Real Name 2001-03-03 23:44:26 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.2.17-14 i686)


The following patch applies to:
"3c59x.c:v0.99Ra 8/7/2000 Donald Becker, becker\n"


*** 3c59x.c     Sun Feb 11 16:16:14 2001
--- 3c59x.c.new Sat Mar  3 15:31:58 2001
***************
*** 23,29 ****
  */
  
  static const char versionA[] =
! "3c59x.c:v0.99Ra 8/7/2000 Donald Becker, becker\n";
  static const char versionB[] =
  "  http://www.scyld.com/network/vortex.html\n";
  
--- 23,29 ----
  */
  
  static const char versionA[] =
! "3c59x.c:v0.99Rb 8/8/2000 Donald Becker, becker\n";
  static const char versionB[] =
  "  http://www.scyld.com/network/vortex.html\n";
  
***************
*** 293,299 ****
         IS_CYCLONE|HAS_NWAY|HAS_CB_FNS| INVERT_LED_PWR | MII_XCVR_PWR, },
        {"3CCFE656B Cyclone+Winmodem CardBus",{ 0x656210B7, 0xffffffff },
         PCI_IOTYPE, CYCLONE_SIZE,
!        IS_CYCLONE|HAS_NWAY|HAS_CB_FNS| INVERT_LED_PWR | MII_XCVR_PWR, },
        {"3CCFE656C Tornado+Winmodem CardBus",{ 0x656410B7, 0xffffffff },
         PCI_IOTYPE, CYCLONE_SIZE,
         IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT | MII_XCVR_PWR, },
--- 293,299 ----
         IS_CYCLONE|HAS_NWAY|HAS_CB_FNS| INVERT_LED_PWR | MII_XCVR_PWR, },
        {"3CCFE656B Cyclone+Winmodem CardBus",{ 0x656210B7, 0xffffffff },
         PCI_IOTYPE, CYCLONE_SIZE,
!       
IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_LED_PWR|MII_XCVR_PWR, },
        {"3CCFE656C Tornado+Winmodem CardBus",{ 0x656410B7, 0xffffffff },
         PCI_IOTYPE, CYCLONE_SIZE,
         IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT | MII_XCVR_PWR, },
***************
*** 466,471 ****
--- 466,472 ----
  
  /* Chip features we care about in vp->capabilities, read from the EEPROM.
*/
  enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };
+ #define resetTmo 200000
  
  #define PRIV_ALIGN    15      /* Required alignment mask */
  struct vortex_private {
***************
*** 1156,1168 ****
        int i;
  
        outw(TxReset, ioaddr + EL3_CMD);
!       for (i = 2000; i >= 0 ; i--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
        outw(RxReset, ioaddr + EL3_CMD);
        /* Wait a few ticks for the RxReset command to complete. */
!       for (i = 2000; i >= 0 ; i--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
--- 1157,1169 ----
        int i;
  
        outw(TxReset, ioaddr + EL3_CMD);
!       for (i = resetTmo; i >= 0 ; i--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
        outw(RxReset, ioaddr + EL3_CMD);
        /* Wait a few ticks for the RxReset command to complete. */
!       for (i = resetTmo; i >= 0 ; i--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
***************
*** 1198,1203 ****
--- 1199,1206 ----
        outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
        outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
        outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+ /*    outw(DownUnstall, ioaddr + EL3_CMD); */
+ /*    outw(UpUnstall, ioaddr + EL3_CMD); */
        /* Allow status bits to be seen. */
        outw(vp->status_enable, ioaddr + EL3_CMD);
        /* Ack all pending events, and set active indicator mask. */
***************
*** 1376,1382 ****
        }
  #endif
        outw(TxReset, ioaddr + EL3_CMD);
!       for (j = 200; j >= 0 ; j--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
--- 1379,1385 ----
        }
  #endif
        outw(TxReset, ioaddr + EL3_CMD);
!       for (j = resetTmo; j >= 0 ; j--)
                if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                        break;
  
***************
*** 1481,1487 ****
                        /* 0x80000000 PCI master abort. */
                        /* 0x40000000 PCI target abort. */
                        outw(TotalReset | 0xff, ioaddr + EL3_CMD);
!                       for (i = 2000; i >= 0 ; i--)
                                if ( ! (inw(ioaddr + EL3_STATUS) &
CmdInProgress))
                                        break;
                        if (vortex_debug)
--- 1484,1490 ----
                        /* 0x80000000 PCI master abort. */
                        /* 0x40000000 PCI target abort. */
                        outw(TotalReset | 0xff, ioaddr + EL3_CMD);
!                       for (i = resetTmo; i >= 0 ; i--)
                                if ( ! (inw(ioaddr + EL3_STATUS) &
CmdInProgress))
                                        break;
                        if (vortex_debug)
***************
*** 1496,1502 ****
                        do_tx_reset = 1;
                if (fifo_diag & 0x3000) {
                        outw(RxReset, ioaddr + EL3_CMD);
!                       for (i = 2000; i >= 0 ; i--)
                                if ( ! (inw(ioaddr + EL3_STATUS) &
CmdInProgress))
                                        break;
                        /* Set the Rx filter to the current state. */
--- 1499,1505 ----
                        do_tx_reset = 1;
                if (fifo_diag & 0x3000) {
                        outw(RxReset, ioaddr + EL3_CMD);
!                       for (i = resetTmo; i >= 0 ; i--)
                                if ( ! (inw(ioaddr + EL3_STATUS) &
CmdInProgress))
                                        break;
                        /* Set the Rx filter to the current state. */
***************
*** 1508,1514 ****
        if (do_tx_reset) {
                int j;
                outw(TxReset, ioaddr + EL3_CMD);
!               for (j = 200; j >= 0 ; j--)
                        if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                                break;
                outw(TxEnable, ioaddr + EL3_CMD);
--- 1511,1517 ----
        if (do_tx_reset) {
                int j;
                outw(TxReset, ioaddr + EL3_CMD);
!               for (j = resetTmo; j >= 0 ; j--)
                        if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
                                break;
                outw(TxEnable, ioaddr + EL3_CMD);
***************
*** 1567,1573 ****
                                if (tx_status & 0x30) {
                                        int j;
                                        outw(TxReset, ioaddr + EL3_CMD);
!                                       for (j = 200; j >= 0 ; j--)
                                                if ( ! (inw(ioaddr +
EL3_STATUS) & CmdInProgress))
                                                        break;
                                }
--- 1570,1576 ----
                                if (tx_status & 0x30) {
                                        int j;
                                        outw(TxReset, ioaddr + EL3_CMD);
!                                       for (j = resetTmo; j >= 0 ; j--)
                                                if ( ! (inw(ioaddr +
EL3_STATUS) & CmdInProgress))
                                                        break;
                                }


Reproducible: Always
Steps to Reproduce:
1.Get a 866Mhz i686 running Redhat 7.0
2.Install 3com 905TXM (latest shipping NIC)
3.Try to use it.
	

Actual Results:  The nic does not work.  The problem is that the
xxReset commands can take up to 1msec to complete
(per the NIC docs from the 3com site).  These
hard coded countdowns are not a good idea.  The
actual timeout trip count should depend on the
cpu speed.

Expected Results:  If you apply the patch, I expect it will work.
If you do not, I expect it will fail.

This was reproduced and verified another user
with a similar system configuration and NIC.
I rate this problem as a severe, since it will
happen on all subsequent installs using the latest
3com adapter (very popular equipment).


Note You need to log in before you can comment on or make changes to this bug.