Changeset 3584398a in rtems


Ignore:
Timestamp:
Jul 18, 2003, 3:52:26 PM (18 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
0ffa407
Parents:
fbbe5fd
Message:

2003-07-18 Greg Menke <gregory.menke@…>

PR 429/bsps
PR 432/bsps

  • network/elnk.c: Due to a bug in the driver, if multiple packets are queued onto an elnk board, the ISR will deadlock the device with a tx complete interrupt. Lighter tx loads are not affected as they end up submitting single packets to the device.
Location:
c/src/libchip
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/ChangeLog

    rfbbe5fd r3584398a  
     12003-07-18      Greg Menke <gregory.menke@gsfc.nasa.gov>
     2
     3        PR 429/bsps
     4        PR 432/bsps
     5        * network/elnk.c: Due to a bug in the driver, if multiple packets
     6        are queued onto an elnk board, the ISR will deadlock the device with
     7        a tx complete interrupt.  Lighter tx loads are not affected as they
     8        end up submitting single packets to the device.
     9
    1102003-07-10      Ralf Corsepius <corsepiu@faw.uni-ulm.de>
    211
  • c/src/libchip/network/elnk.c

    rfbbe5fd r3584398a  
    7171 */
    7272
    73 /*
    7473#if defined(__i386__)
    7574#define ELNK_SUPPORTED
    7675#endif
    77 */
    7876
    7977#if defined(__PPC__) && (defined(mpc604) || defined(mpc750) || defined(mpc603e))
     
    117115#if defined(__i386__)
    118116#include <irq.h>
    119 #endif
    120 #if defined(__PPC)
     117
     118#define IO_MASK   0x3
     119#define MEM_MASK  0xF
     120
     121#endif
     122#if defined(__PPC__)
    121123#include <bsp/irq.h>
    122124#endif
     
    192194
    193195
    194 #if defined(__PPC)
     196#if defined(__PPC__)
    195197#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
    196198#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
     
    780782      u_int8_t          txstatus;
    781783      u_int16_t         mediastatus;
     784
     785      u_int32_t         txcomplete_ints;
    782786
    783787      u_int16_t         miianr, miipar, miistatus, miicmd;
     
    865869
    866870
    867 
    868 
    869 
    870 
    871 #define CSR_WRITE_4(sc, reg, val)       outl( val, sc->ioaddr + reg)
    872 #define CSR_WRITE_2(sc, reg, val)       outw( val, sc->ioaddr + reg)
    873 #define CSR_WRITE_1(sc, reg, val)       outb( val, sc->ioaddr + reg)
    874 
    875 #define CSR_READ_4(sc, reg)             inl(sc->ioaddr + reg)
    876 #define CSR_READ_2(sc, reg)             inw(sc->ioaddr + reg)
    877 #define CSR_READ_1(sc, reg)             inb(sc->ioaddr + reg)
    878 
    879 #define XL_SEL_WIN(x)                   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x)
    880 
    881871#define XL_TIMEOUT              1000
    882872
     
    903893
    904894
    905 #define NUM_FRAGS       8
     895#define NUM_FRAGS       6
    906896
    907897/*
     
    979969static rtems_id chainRecoveryQueue;
    980970
     971
     972
     973
     974
     975
     976
     977#if defined(__i386__)
     978
     979#define CSR_WRITE_4(sc, reg, val)       i386_outport_long( sc->ioaddr + reg, val )
     980#define CSR_WRITE_2(sc, reg, val)       i386_outport_word( sc->ioaddr + reg, val )
     981#define CSR_WRITE_1(sc, reg, val)       i386_outport_byte( sc->ioaddr + reg, val )
     982
     983
     984inline unsigned int CSR_READ_4( struct elnk_softc *sc, int reg)
     985{
     986   unsigned int myval;
     987   i386_inport_long( sc->ioaddr + reg, myval );
     988   return myval;
     989}
     990
     991inline unsigned short  CSR_READ_2( struct elnk_softc *sc, int reg)
     992{
     993   unsigned short myval;
     994   i386_inport_word( sc->ioaddr + reg, myval );
     995   return myval;
     996}
     997
     998inline unsigned char CSR_READ_1( struct elnk_softc *sc, int reg)
     999{
     1000   unsigned char myval;
     1001   i386_inport_byte( sc->ioaddr + reg, myval );
     1002   return myval;
     1003}
     1004
     1005#endif
     1006
     1007#if defined(__PPC__)
     1008
     1009#define CSR_WRITE_4(sc, reg, val)       outl( val, sc->ioaddr + reg)
     1010#define CSR_WRITE_2(sc, reg, val)       outw( val, sc->ioaddr + reg)
     1011#define CSR_WRITE_1(sc, reg, val)       outb( val, sc->ioaddr + reg)
     1012
     1013#define CSR_READ_4(sc, reg)             inl(sc->ioaddr + reg)
     1014#define CSR_READ_2(sc, reg)             inw(sc->ioaddr + reg)
     1015#define CSR_READ_1(sc, reg)             inb(sc->ioaddr + reg)
     1016
     1017#endif
     1018
     1019
     1020#define XL_SEL_WIN(x)                   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x)
    9811021
    9821022
     
    19051945      }
    19061946
    1907       if (status & XL_STAT_DOWN_COMPLETE)
     1947      if( (status & XL_STAT_DOWN_COMPLETE) || (status & XL_STAT_TX_COMPLETE) )
    19081948      {
    19091949         /* all packets uploaded to the device */
    19101950         struct TXMD *chaintailmd = NULL;
    19111951
     1952
     1953         if( status & XL_STAT_TX_COMPLETE )
     1954         {
     1955            /* if we got a tx complete error, count it, then reset the
     1956               transmitter.  Consider the entire chain lost.. */
     1957
     1958            ifp->if_oerrors++;
     1959            sc->xl_stats.txcomplete_ints++;
     1960
     1961            printk("etherlink : unit elnk%d transmit error\n", sc->xl_unit );
     1962
     1963            /* reset, re-enable fifo */
     1964
     1965            xl_wait(sc);
     1966            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
     1967
     1968            xl_wait(sc);
     1969            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET | 1 );
     1970
     1971            xl_wait(sc);
     1972            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
     1973
     1974            xl_wait(sc);
     1975         }
     1976
     1977
    19121978         /* send the chain head to the tx task which will recover the
    19131979            whole chain */
    19141980         rtems_message_queue_send( chainRecoveryQueue, &sc->last_txchain_head, sizeof(struct TXMD *));
     1981
    19151982
    19161983         /* set up the next chain */
     
    19382005               ** otherwise, this is a pointer to the last packet in the
    19392006               ** chain of 2 or more packets.  If the chain's last
    1940                ** packet's mbuf is != 0, then another chain is ready to
    1941                ** send.
     2007               ** packet's chainptr is != 0, then another chain is ready
     2008               ** to send.
    19422009               */
    19432010               chaintailmd = sc->last_txchain_head->chainptr;
    1944                if( !chaintailmd->mbuf ) chaintailmd = NULL;
     2011               if( !chaintailmd->chainptr ) chaintailmd = NULL;
    19452012            }
    19462013         }
     
    19662033
    19672034
    1968       if (status & XL_STAT_TX_COMPLETE)
    1969       {
    1970          ifp->if_oerrors++;
    1971          {
    1972             unsigned32 txstat;
    1973 
    1974             XL_SEL_WIN(1);
    1975             txstat  = CSR_READ_1(sc, XL_W1_TX_STATUS );
    1976             XL_SEL_WIN(7);
    1977            
    1978             printk("etherlink : unit elnk%d transmit error, txstat = %02x \n", sc->xl_unit, txstat );
    1979 
    1980             xl_wait(sc);
    1981             CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
    1982             xl_wait(sc);
    1983             CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
    1984             xl_wait(sc);
    1985          }
    1986       }
    19872035      if (status & XL_STAT_ADFAIL)
    19882036      {
     
    23172365
    23182366
    2319 
    2320 
    2321 
    2322 
    23232367/*
    23242368 * Driver transmit daemon
     
    23552399                * Send packets till queue is empty or tx ring is full
    23562400                */
     2401
    23572402               chainCount = 0;
    23582403               firstmd = NULL;
     
    23622407               for(;;)
    23632408               {
    2364 
    23652409                  /*
    23662410                  ** Check the chain recovery queue whenever the tx
    2367                   ** daemon wakes up.  Note this routine does not assume
    2368                   ** the context of one of the lanboard units because
    2369                   ** used tx mbufs no longer associated with any unit.
     2411                  ** daemon services the stack.  Note this routine does
     2412                  ** not assume the context of one of the lanboard units
     2413                  ** because used tx mbufs are no longer associated with
     2414                  ** any unit.
    23702415                  */
    23712416                  {
     
    23862431                           {
    23872432                              m_freem( chainhead->mbuf );
     2433                              st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
    23882434                              chainhead->mbuf = NULL;
    23892435
     
    23962442                           /* a single packet chain */
    23972443                           m_freem( chainhead->mbuf );
     2444                           st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
    23982445                           chainhead->mbuf = NULL;
    23992446                        }
     
    24012448                  }
    24022449
    2403 
    2404 
    24052450                  nextmd = lastmd->next_md;
    24062451
    24072452                  /* stop when ring is full */
    2408                   if( nextmd->mbuf || ! (ld_le32(&nextmd->status) & XL_TXSTAT_DL_COMPLETE) )
     2453                  if( ! (ld_le32(&nextmd->status) & XL_TXSTAT_DL_COMPLETE) )
    24092454                  {
    24102455                     printk("etherlink : unit elnk%d tx ring full!\n", sc->xl_unit);
    24112456                     break;
    24122457                  }
     2458                  /* sanity check the next packet descriptor */
     2459                  if( nextmd->mbuf )
     2460                  {
     2461                     printk("etherlink : unit elnk%d tx ring corrupt!\n", sc->xl_unit);
     2462                     break;
     2463                  }
     2464
    24132465                 
    24142466
     
    24242476                     {
    24252477                        st_le32( &nextmd->txfrags[i].length, ((m->m_next)?0:XL_LAST_FRAG) | ( m->m_len & XL_TXSTAT_LENMASK) );
    2426                         st_le32( &nextmd->txfrags[i].addr, (unsigned32)phys_to_bus(m->m_data) );
     2478                        st_le32( &nextmd->txfrags[i].addr, (unsigned32)phys_to_bus( m->m_data ) );
    24272479                        if ((m = m->m_next) == NULL)
    24282480                           break;
     
    24382490#if 0
    24392491                  {
    2440                      char *pkt = bus_to_phys( ld_le32( &nextmd->txfrags[i].addr ), *delim;
     2492                     char *pkt = bus_to_phys( ld_le32( &nextmd->txfrags[i].addr )), *delim;
    24412493                     int  i;
    24422494                     printk("unit %d queued  pkt (%08x) ", sc->xl_unit, (unsigned32)pkt );
     
    24802532
    24812533
     2534
     2535
    24822536               if( firstmd )
    24832537               {
    2484                   /* only entered if we've queued one or more packets */
     2538                  /* only enter if we've queued one or more packets */
    24852539
    24862540                  /* save the last descriptor we set up in the chain */
     
    24952549
    24962550                  /*
    2497                    * point the chain head's mbuf to the tail so we can
    2498                    * locate the next chain to send inside the isr.  If
    2499                    * we're only sending one packet, then don't bother
    2500                    * with the link, as the chainptr value will either be 0
    2501                    * if theres no next chain or -1 if there is.
     2551                   * point the chain head's chainptr to the tail so we
     2552                   * can jump to the next chain to send inside the isr.
     2553                   * If we're only sending one packet, then don't bother
     2554                   * with the link, as the chainptr value will either be
     2555                   * 0 if theres no next chain or -1 if there is.
    25022556                   */
    25032557                  if( chainCount > 1 )
     
    25112565                  /*
    25122566                  ** clear the last packet's chainptr flag.  If another
    2513                   ** chain is added later, before this chain is finished
    2514                   ** being sent, the flag on this packet will be re-set
    2515                   ** to -1
     2567                  ** chain is added later but before this chain is
     2568                  ** finished being sent, this flag on this packet will
     2569                  ** be re-set to -1
    25162570                  */
    25172571                  lastmd->chainptr = NULL;
     
    25432597                  }
    25442598               }
     2599
    25452600
    25462601               ifp->if_flags &= ~IFF_OACTIVE;
     
    29402995      }
    29412996
    2942       printf("          interrupts:%-9d    avg_chain_len:%-5d\n",
     2997      printf("          interrupts:%-9d       txcmp_ints:%-5d  avg_chain_len:%-4d\n",
    29432998             sc->xl_stats.device_interrupts,
     2999             sc->xl_stats.txcomplete_ints,
    29443000             (totalLengths / numLengths) );
    29453001   }
     
    30793135   int          mtu, i;
    30803136   unsigned char cvalue;
    3081    int          pbus, pdev, pfun;
    3082    unsigned int lvalue;
    30833137   struct el_boards         sysboards[NUM_UNITS];
    30843138   int                      numFound = 0;
     3139   int          pbus, pdev, pfun;
     3140#if defined(__i386__)
     3141   int          signature;
     3142   int          value;
     3143   char         interrupt;
     3144#endif
     3145#if defined(__PPC__)
     3146   unsigned int lvalue;
     3147#endif
    30853148
    30863149
     
    31173180      for( i=0; !done && xl_devs[i].xl_vid; i++)
    31183181      {
    3119          for(unum= 1;
    3120              !done && BSP_pciFindDevice( xl_devs[i].xl_vid, xl_devs[i].xl_did, unum-1,
     3182         for(unum= 1; !done && BSP_pciFindDevice( xl_devs[i].xl_vid, xl_devs[i].xl_did, unum-1,
    31213183                                         &sysboards[numFound].pbus,
    31223184                                         &sysboards[numFound].pdev,
    3123                                          &sysboards[numFound].pfun)==0;
    3124              unum++)
     3185                                                  &sysboards[numFound].pfun)==0; unum++)
    31253186         {
    31263187            if( numFound == NUM_UNITS )
     
    31873248      pdev = sysboards[unitNumber-1].pdev;
    31883249      pfun = sysboards[unitNumber-1].pfun;
     3250#if defined(__i386__)
     3251      signature = PCIB_DEVSIG_MAKE(pbus,pdev,pfun);
     3252#endif
    31893253   }
    31903254
     
    32533317
    32543318
     3319#if defined(__i386__)
     3320   pcib_conf_read32(signature, 16, &value);
     3321   sc->ioaddr = value & ~IO_MASK;
     3322
     3323   pcib_conf_read8(signature, 60, &interrupt);
     3324   cvalue = interrupt;
     3325#endif
     3326#if defined(__PPC__)
    32553327   /*
    32563328   ** Prep the board
     
    32623334                                       PCI_COMMAND_INVALIDATE |
    32633335                                       PCI_COMMAND_WAIT ) );
    3264 
    32653336   /*
    3266     * Get the devices base address
     3337    * Get the device's base address
    32673338    */
    32683339   pci_read_config_dword(pbus, pdev, pfun,
     
    32713342
    32723343   sc->ioaddr = (unsigned32)lvalue & PCI_BASE_ADDRESS_IO_MASK;
    3273        
    3274 
    32753344   /*
    32763345   ** Store the interrupt name, we'll use it later when we initialize
     
    32803349                        PCI_INTERRUPT_LINE,
    32813350                        &cvalue);
     3351#endif       
    32823352
    32833353   memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
     
    32983368         when the timer expires during a transfer.  This bug exists the Vortex
    32993369         chip only. */
     3370#if defined(__i386__)
     3371      pcib_conf_read8(signature, 0x0d, &pci_latency);
     3372#endif
     3373#if defined(__PPC__)
    33003374      pci_read_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, &pci_latency);
     3375#endif
    33013376      if (pci_latency < new_latency)
    33023377      {
    33033378         printk("etherlink : unit elnk%d Overriding PCI latency, timer (CFLT) setting of %d, new value is %d.\n", sc->xl_unit, pci_latency, new_latency );
     3379#if defined(__i386__)
     3380         pcib_conf_write8(signature, 0x0d, new_latency);
     3381#endif
     3382#if defined(__PPC__)
    33043383         pci_write_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, new_latency);
     3384#endif
    33053385      }
    33063386   }
Note: See TracChangeset for help on using the changeset viewer.