Changeset f1f42b4 in rtems


Ignore:
Timestamp:
03/23/99 22:51:05 (24 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
da7a73e
Parents:
b6f5f93
Message:

Modifications from Jiri Gaisler <jgais@…> to
fix some problems encountered when reusing this driver on
a SPARC ERC32 based Tharsys board. He eliminted the need
for TX interrupts and added code that can optionally ensure that
the IP address is 32-bit aligned. He also fixed a handful of
problems that only occured because the 8 Mhz ERC32 was
enough slower than the 100 Mhz PPC603e that timing
issues in this driver were magnified.

Location:
c/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libchip/network/sonic.c

    rb6f5f93 rf1f42b4  
    2424 *
    2525 *  $Id$
     26 *
     27 *  This driver was originally written and tested on a DY-4 DMV177,
     28 *  which had a 100 Mhz PPC603e.
     29 *
     30 *  This driver also works with DP83934CVUL-20/25 MHz, tested on
     31 *  Tharsys ERC32 VME board.
     32 *
     33 *  Rehaul to fix lost interrupts and buffers, and to use to use
     34 *  interrupt-free transmission by Jiri, 22/03/1999.
    2635 */
    2736
     
    5160
    5261void *set_vector(void *, unsigned32, unsigned32);
    53 
    54 /*
    55  * Debug levels
    56  *
    57  */
    58 
    59 #define SONIC_DEBUG_NONE                0x0000
    60 #define SONIC_DEBUG_ALL                 0xFFFF
    61 #define SONIC_DEBUG_PRINT_REGISTERS     0x0001
    62 #define SONIC_DEBUG_MEMORY              0x0002
    63 #define SONIC_DEBUG_MEMORY_ALLOCATE     0x0004
    64 #define SONIC_DEBUG_MEMORY_DESCRIPTORS  0x0008
    65 #define SONIC_DEBUG_FRAGMENTS           0x0008
    66 #define SONIC_DEBUG_CAM                 0x0010
    67 #define SONIC_DEBUG_DESCRIPTORS         0x0020
    68 #define SONIC_DEBUG_ERRORS              0x0040
    69 #define SONIC_DEBUG_DUMP_TX_MBUFS       0x0080
    70 #define SONIC_DEBUG_DUMP_RX_MBUFS       0x0100
    71 
    72 #define SONIC_DEBUG_DUMP_MBUFS \
    73   (SONIC_DEBUG_DUMP_TX_MBUFS|SONIC_DEBUG_DUMP_RX_MBUFS)
    74 
    75 #define SONIC_DEBUG  (SONIC_DEBUG_ERRORS)
    76 
    77 /*
    78   ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_PRINT_REGISTERS|SONIC_DEBUG_DUMP_MBUFS))
    79   ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_DUMP_MBUFS))
    80 */
    81 
    8262
    8363#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_MBUFS)
     
    202182  TransmitDescriptorPointer_t     tdaHead;  /* Last filled */
    203183  TransmitDescriptorPointer_t     tdaTail;  /* Next to retire */
    204   int                             tdaActiveCount;
    205184
    206185  /*
     
    300279}
    301280
     281void sonic_disable_interrupts(
     282  struct sonic_softc *sc,
     283  unsigned32  mask
     284)
     285{
     286  void *rp = sc->sonic;
     287  rtems_interrupt_level level;
     288
     289  rtems_interrupt_disable( level );
     290  (*sc->write_register)(
     291         rp,
     292         SONIC_REG_IMR,
     293         (*sc->read_register)(rp, SONIC_REG_IMR) & ~mask
     294      );
     295  rtems_interrupt_enable( level );
     296}
     297
     298void sonic_clear_interrupts(
     299  struct sonic_softc *sc,
     300  unsigned32  mask
     301)
     302{
     303  void *rp = sc->sonic;
     304  rtems_interrupt_level level;
     305
     306  rtems_interrupt_disable( level );
     307  (*sc->write_register)( rp, SONIC_REG_ISR, mask);
     308  rtems_interrupt_enable( level );
     309}
     310
     311void sonic_command(
     312  struct sonic_softc *sc,
     313  unsigned32  mask
     314)
     315{
     316  void *rp = sc->sonic;
     317  rtems_interrupt_level level;
     318
     319  rtems_interrupt_disable( level );
     320  (*sc->write_register)( rp, SONIC_REG_CR, mask);
     321  rtems_interrupt_enable( level );
     322}
     323
    302324/*
    303325 * Allocate non-cacheable memory on a single 64k page.
     
    335357SONIC_STATIC void sonic_stop (struct sonic_softc *sc)
    336358{
    337   void *rp = sc->sonic;
    338359  struct ifnet *ifp = &sc->arpcom.ac_if;
    339360
     
    343364   * Stop the transmitter and receiver.
    344365   */
    345   (*sc->write_register)( rp, SONIC_REG_CR, CR_HTX | CR_RXDIS );
     366  sonic_command(sc, CR_HTX | CR_RXDIS );
    346367}
    347368
     
    410431   * Packet received or receive buffer area exceeded?
    411432   */
    412   if ((imr & (IMR_PRXEN | IMR_RBAEEN)) &&
    413       (isr & (ISR_PKTRX | ISR_RBAE))) {
     433  if (imr & isr & (IMR_PRXEN | IMR_RBAEEN)) {
    414434    imr &= ~(IMR_PRXEN | IMR_RBAEEN);
    415435    sc->rxInterrupts++;
    416436    rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
     437    (*sc->write_register)( rp, SONIC_REG_IMR, imr );
     438    (*sc->write_register)( rp, SONIC_REG_ISR, isr & ISR_PKTRX );
    417439  }
    418440
    419441  /*
    420442   * Packet started, transmitter done or transmitter error?
    421    */
    422   if ((imr & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)) &&
    423       (isr & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
    424     imr &= ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
     443   * TX interrupts only occur after an error or when all TDA's are
     444   * exhausted and we are waiting for buffer to come free.
     445   */
     446  if (imr & isr & (IMR_PINTEN | IMR_TXEREN)) {
    425447    sc->txInterrupts++;
    426448    rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
    427   }
    428 
    429   (*sc->write_register)( rp, SONIC_REG_IMR, imr );
     449    (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
     450  }
     451
    430452}
    431453
     
    451473   * Repeat for all completed transmit descriptors.
    452474   */
    453   while ((sc->tdaActiveCount != 0)
    454       && ((status = sc->tdaTail->status) != 0)) {
     475  while ((status = sc->tdaTail->status) != 0) {
    455476
    456477#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
     
    491512
    492513        (*sc->write_register)( rp, SONIC_REG_CTDA, link );
    493         (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
     514        sonic_command(sc, CR_TXP );
    494515      }
    495516    }
     
    522543     *  Free the packet and reset a couple of fields
    523544     */
    524     sc->tdaActiveCount--;
    525545    m = sc->tdaTail->mbufp;
    526546    while ( m ) {
     
    529549    }
    530550
     551    /*
    531552    sc->tdaTail->frag[0].frag_link = LSW(sc->tdaTail->link_pad);
    532553    sc->tdaTail->frag_count        = 0;
     554    */
     555    sc->tdaTail->status        = 0;
    533556
    534557    /*
     
    548571{
    549572  struct sonic_softc *sc = ifp->if_softc;
    550   void *rp = sc->sonic;
    551573  struct mbuf *l = NULL;
    552574  TransmitDescriptorPointer_t tdp;
     
    554576  unsigned int packetSize;
    555577  int i;
     578  rtems_event_set events;
    556579  static char padBuf[64];
    557580
    558581  /* printf( "sonic_sendpacket %p\n", m ); */
    559   /*
    560    * Free up transmit descriptors.
    561    */
    562   sonic_retire_tda (sc);
    563 
    564   /*
    565    * Wait for transmit descriptor to become available.
    566    */
    567   if (sc->tdaActiveCount == sc->tdaCount) {
     582
     583
     584  /*
     585   * Wait for transmit descriptor to become available. Only retire TDA's
     586   * if there are no more free buffers to minimize TX latency. Retire TDA'a
     587   * on the way out.
     588   */
     589
     590  while (sc->tdaHead->next->status != 0) {
     591 
     592  /*
     593   * Free up transmit descriptors
     594   */
     595    sonic_retire_tda (sc);
     596
     597    if (sc->tdaHead->next->status == 0)
     598      break;
     599
    568600#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
    569     puts( "Wait for more TDAs" );
    570 #endif
    571 
    572     /*
    573      * Clear old events.
    574      */
    575     (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
    576 
    577     /*
    578      * Wait for transmit descriptor to become available.
    579      * Note that the transmit descriptors are checked
    580      * *before* * entering the wait loop -- this catches
    581      * the possibility that a transmit descriptor became
    582      * available between the `if' the started this block,
    583      * and the clearing of the interrupt status register.
    584      */
    585     sonic_retire_tda (sc);
    586     while (sc->tdaActiveCount == sc->tdaCount) {
    587       rtems_event_set events;
    588 
    589 #if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
    590       printf("blocking until TDAs are available\n");
     601    printf("blocking until TDAs are available\n");
    591602#endif
    592603      /*
    593        * Enable transmitter interrupts.
     604       * Enable PINT interrupts.
     605    sonic_clear_interrupts( sc, ISR_PINT );
     606    sonic_enable_interrupts( sc, IMR_PINTEN );
    594607       */
    595       sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
    596608
    597609      /*
    598        * Wait for interrupt
     610       * Wait for PINT TX interrupt. Every fourth TX buffer will raise PINT.
    599611       */
    600       rtems_bsdnet_event_receive (INTERRUPT_EVENT,
     612    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
    601613            RTEMS_WAIT|RTEMS_EVENT_ANY,
    602614            RTEMS_NO_TIMEOUT,
    603615            &events);
    604       (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
    605       sonic_retire_tda (sc);
    606     }
     616    sonic_disable_interrupts( sc, IMR_PINTEN );
     617    sonic_retire_tda (sc);
    607618  }
    608619
     
    686697  if ( sc->tdaHead->frag_count )
    687698    *sc->tdaHead->linkp &= ~TDA_LINK_EOL;
    688   sc->tdaActiveCount++;
    689699  sc->tdaHead = tdp;
    690700
    691 /* XXX not in KA9Q */
    692   sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
    693   (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
     701  /* Start transmission */
     702
     703  sonic_command(sc, CR_TXP );
     704
     705  /*
     706   * Free up transmit descriptors on the way out.
     707   */
     708  sonic_retire_tda (sc);
    694709}
    695710
     
    837852       * Restart reception
    838853       */
    839       (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBAE );
    840       (*sc->write_register)( rp, SONIC_REG_CR, CR_RXEN );
     854      sonic_clear_interrupts( sc, ISR_RBAE );
     855      sonic_command( sc, CR_RXEN );
    841856    }
    842 
    843     /*
    844      * Clear old packet-received events.
    845      */
    846     (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PKTRX );
    847857
    848858    /*
     
    934944#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
    935945      sonic_print_rx_descriptor( rdp );
    936 #endif
     946      if ((LSW(rdp->mbufp->m_data) != rdp->pkt_lsw)
     947       || (MSW(rdp->mbufp->m_data) != rdp->pkt_msw))
     948        printf ("SONIC RDA/RRA %p, %08x\n",rdp->mbufp->m_data,(rdp->pkt_msw << 16) |
     949        (rdp->pkt_lsw & 0x0ffff));
     950#endif
     951      rdp->byte_count &= 0x0ffff;    /* ERC32 pollutes msb of byte_count */
    937952      m = rdp->mbufp;
    938953      m->m_len = m->m_pkthdr.len = rdp->byte_count -
     
    942957      m->m_data += sizeof(struct ether_header);
    943958 
     959#ifdef CPU_U32_FIX
     960      ipalign(m);       /* Align packet on 32-bit boundary */
     961#endif
     962
    944963#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_RX_MBUFS)
    945964      Dump_Buffer( (void *) eh, sizeof(struct ether_header) );
     
    948967
    949968      /* printf( "ether_input %p\n", m ); */
     969      /*
     970      printf( "pkt %p, seq %04x, mbuf %p, m_data %p\n", rdp, rdp->seq_no, m, m->m_data );
     971      printf( "%u, %u\n", ((int*)m->m_data)[6], ((int*)m->m_data)[7]);
     972      */
    950973      ether_input (ifp, eh, m);
     974      /*
     975      */
    951976
    952977      /*
     
    9961021       */
    9971022      if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBE)
    998         (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBE );
     1023      sonic_clear_interrupts( sc, ISR_RBE );
    9991024    }
    10001025    else {
     
    10171042
    10181043    /*
    1019      * Move to next receive descriptor
    1020      */
    1021 
     1044     * Move to next receive descriptor and update EOL
     1045     */
     1046
     1047    rdp->link |= RDA_LINK_EOL;
    10221048    rdp->in_use = RDA_FREE;
     1049    sc->rdp_last->link &= ~RDA_LINK_EOL;
     1050    sc->rdp_last = rdp;
    10231051    rdp = rdp->next;
    1024     rdp->link &= ~RDA_LINK_EOL;
    10251052
    10261053  }
     
    10591086   */
    10601087
    1061   if ( (*sc->read_register)( rp, SONIC_REG_SR ) < SONIC_REVISION_C ) {
     1088  if ( (*sc->read_register)( rp, SONIC_REG_SR ) <= SONIC_REVISION_B ) {
    10621089    rtems_fatal_error_occurred( 0x0BADF00D );  /* don't eat this part :) */
    10631090  }
     
    10711098   */
    10721099
    1073   sc->tdaActiveCount = 0;
    10741100  sc->tdaTail = sonic_allocate(sc->tdaCount * sizeof *tdp);
    10751101#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
     
    10881114
    10891115/* XXX not used by the BSD drivers
     1116    tdp->frag[0].frag_link = LSW(tdp + 1);
    10901117*/
    1091     if (i & 1)
     1118    if (i & 3)
    10921119      tdp->pkt_config = TDA_CONFIG_PINT;
    10931120
    1094     tdp->frag_count        = 0;
    1095     tdp->frag[0].frag_link = LSW(tdp + 1);
    1096     tdp->link_pad          = LSW(tdp + 1) | TDA_LINK_EOL;
    1097     tdp->linkp             = &((tdp + 1)->frag[0].frag_link);
    1098     tdp->next              = (TransmitDescriptor_t *)(tdp + 1);
     1121    tdp->status         = 0;
     1122    tdp->frag_count     = 0;
     1123    tdp->link_pad       = LSW(tdp + 1) | TDA_LINK_EOL;
     1124    tdp->linkp          = &((tdp + 1)->frag[0].frag_link);
     1125    tdp->next           = (TransmitDescriptor_t *)(tdp + 1);
    10991126#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
    11001127    sonic_print_tx_descriptor( tdp );
     
    11431170  ordp->next   = sc->rda;
    11441171  ordp->link   = LSW(sc->rda) | RDA_LINK_EOL;
    1145   sc->rdp_last = rdp;
     1172  sc->rdp_last = ordp;
    11461173 
    11471174  /*
     
    13201347        (*sc->read_register)( rp, SONIC_REG_CAP0 ),
    13211348        (*sc->read_register)( rp, SONIC_REG_CE ));
    1322 #endif
    13231349
    13241350  (*sc->write_register)( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */
     
    13371363    rtems_panic ("SONIC LCAM");
    13381364  }
     1365#endif
    13391366
    13401367  (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);
     
    13871414     * Start driver tasks
    13881415     */
     1416    sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
    13891417    sc->txDaemonTid = rtems_bsdnet_newproc ("SNtx", 4096, sonic_txDaemon, sc);
    1390     sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
    13911418  }
    13921419
     
    14091436   * Enable receiver and transmitter
    14101437   */
    1411   /* (*sc->write_register)( rp, SONIC_REG_IMR, 0 ); */
    1412   sonic_enable_interrupts( sc,
    1413         (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) | (IMR_PRXEN | IMR_RBAEEN) );
    1414 
    1415   (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */ CR_RXEN);
     1438  sonic_enable_interrupts( sc, IMR_TXEREN | (IMR_PRXEN | IMR_RBAEEN) );
     1439  sonic_command( sc, CR_RXEN );
    14161440}
    14171441
  • c/src/libchip/network/sonic.c

    rb6f5f93 rf1f42b4  
    2424 *
    2525 *  $Id$
     26 *
     27 *  This driver was originally written and tested on a DY-4 DMV177,
     28 *  which had a 100 Mhz PPC603e.
     29 *
     30 *  This driver also works with DP83934CVUL-20/25 MHz, tested on
     31 *  Tharsys ERC32 VME board.
     32 *
     33 *  Rehaul to fix lost interrupts and buffers, and to use to use
     34 *  interrupt-free transmission by Jiri, 22/03/1999.
    2635 */
    2736
     
    5160
    5261void *set_vector(void *, unsigned32, unsigned32);
    53 
    54 /*
    55  * Debug levels
    56  *
    57  */
    58 
    59 #define SONIC_DEBUG_NONE                0x0000
    60 #define SONIC_DEBUG_ALL                 0xFFFF
    61 #define SONIC_DEBUG_PRINT_REGISTERS     0x0001
    62 #define SONIC_DEBUG_MEMORY              0x0002
    63 #define SONIC_DEBUG_MEMORY_ALLOCATE     0x0004
    64 #define SONIC_DEBUG_MEMORY_DESCRIPTORS  0x0008
    65 #define SONIC_DEBUG_FRAGMENTS           0x0008
    66 #define SONIC_DEBUG_CAM                 0x0010
    67 #define SONIC_DEBUG_DESCRIPTORS         0x0020
    68 #define SONIC_DEBUG_ERRORS              0x0040
    69 #define SONIC_DEBUG_DUMP_TX_MBUFS       0x0080
    70 #define SONIC_DEBUG_DUMP_RX_MBUFS       0x0100
    71 
    72 #define SONIC_DEBUG_DUMP_MBUFS \
    73   (SONIC_DEBUG_DUMP_TX_MBUFS|SONIC_DEBUG_DUMP_RX_MBUFS)
    74 
    75 #define SONIC_DEBUG  (SONIC_DEBUG_ERRORS)
    76 
    77 /*
    78   ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_PRINT_REGISTERS|SONIC_DEBUG_DUMP_MBUFS))
    79   ((SONIC_DEBUG_ALL) & ~(SONIC_DEBUG_DUMP_MBUFS))
    80 */
    81 
    8262
    8363#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_MBUFS)
     
    202182  TransmitDescriptorPointer_t     tdaHead;  /* Last filled */
    203183  TransmitDescriptorPointer_t     tdaTail;  /* Next to retire */
    204   int                             tdaActiveCount;
    205184
    206185  /*
     
    300279}
    301280
     281void sonic_disable_interrupts(
     282  struct sonic_softc *sc,
     283  unsigned32  mask
     284)
     285{
     286  void *rp = sc->sonic;
     287  rtems_interrupt_level level;
     288
     289  rtems_interrupt_disable( level );
     290  (*sc->write_register)(
     291         rp,
     292         SONIC_REG_IMR,
     293         (*sc->read_register)(rp, SONIC_REG_IMR) & ~mask
     294      );
     295  rtems_interrupt_enable( level );
     296}
     297
     298void sonic_clear_interrupts(
     299  struct sonic_softc *sc,
     300  unsigned32  mask
     301)
     302{
     303  void *rp = sc->sonic;
     304  rtems_interrupt_level level;
     305
     306  rtems_interrupt_disable( level );
     307  (*sc->write_register)( rp, SONIC_REG_ISR, mask);
     308  rtems_interrupt_enable( level );
     309}
     310
     311void sonic_command(
     312  struct sonic_softc *sc,
     313  unsigned32  mask
     314)
     315{
     316  void *rp = sc->sonic;
     317  rtems_interrupt_level level;
     318
     319  rtems_interrupt_disable( level );
     320  (*sc->write_register)( rp, SONIC_REG_CR, mask);
     321  rtems_interrupt_enable( level );
     322}
     323
    302324/*
    303325 * Allocate non-cacheable memory on a single 64k page.
     
    335357SONIC_STATIC void sonic_stop (struct sonic_softc *sc)
    336358{
    337   void *rp = sc->sonic;
    338359  struct ifnet *ifp = &sc->arpcom.ac_if;
    339360
     
    343364   * Stop the transmitter and receiver.
    344365   */
    345   (*sc->write_register)( rp, SONIC_REG_CR, CR_HTX | CR_RXDIS );
     366  sonic_command(sc, CR_HTX | CR_RXDIS );
    346367}
    347368
     
    410431   * Packet received or receive buffer area exceeded?
    411432   */
    412   if ((imr & (IMR_PRXEN | IMR_RBAEEN)) &&
    413       (isr & (ISR_PKTRX | ISR_RBAE))) {
     433  if (imr & isr & (IMR_PRXEN | IMR_RBAEEN)) {
    414434    imr &= ~(IMR_PRXEN | IMR_RBAEEN);
    415435    sc->rxInterrupts++;
    416436    rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
     437    (*sc->write_register)( rp, SONIC_REG_IMR, imr );
     438    (*sc->write_register)( rp, SONIC_REG_ISR, isr & ISR_PKTRX );
    417439  }
    418440
    419441  /*
    420442   * Packet started, transmitter done or transmitter error?
    421    */
    422   if ((imr & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)) &&
    423       (isr & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
    424     imr &= ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN);
     443   * TX interrupts only occur after an error or when all TDA's are
     444   * exhausted and we are waiting for buffer to come free.
     445   */
     446  if (imr & isr & (IMR_PINTEN | IMR_TXEREN)) {
    425447    sc->txInterrupts++;
    426448    rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
    427   }
    428 
    429   (*sc->write_register)( rp, SONIC_REG_IMR, imr );
     449    (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
     450  }
     451
    430452}
    431453
     
    451473   * Repeat for all completed transmit descriptors.
    452474   */
    453   while ((sc->tdaActiveCount != 0)
    454       && ((status = sc->tdaTail->status) != 0)) {
     475  while ((status = sc->tdaTail->status) != 0) {
    455476
    456477#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
     
    491512
    492513        (*sc->write_register)( rp, SONIC_REG_CTDA, link );
    493         (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
     514        sonic_command(sc, CR_TXP );
    494515      }
    495516    }
     
    522543     *  Free the packet and reset a couple of fields
    523544     */
    524     sc->tdaActiveCount--;
    525545    m = sc->tdaTail->mbufp;
    526546    while ( m ) {
     
    529549    }
    530550
     551    /*
    531552    sc->tdaTail->frag[0].frag_link = LSW(sc->tdaTail->link_pad);
    532553    sc->tdaTail->frag_count        = 0;
     554    */
     555    sc->tdaTail->status        = 0;
    533556
    534557    /*
     
    548571{
    549572  struct sonic_softc *sc = ifp->if_softc;
    550   void *rp = sc->sonic;
    551573  struct mbuf *l = NULL;
    552574  TransmitDescriptorPointer_t tdp;
     
    554576  unsigned int packetSize;
    555577  int i;
     578  rtems_event_set events;
    556579  static char padBuf[64];
    557580
    558581  /* printf( "sonic_sendpacket %p\n", m ); */
    559   /*
    560    * Free up transmit descriptors.
    561    */
    562   sonic_retire_tda (sc);
    563 
    564   /*
    565    * Wait for transmit descriptor to become available.
    566    */
    567   if (sc->tdaActiveCount == sc->tdaCount) {
     582
     583
     584  /*
     585   * Wait for transmit descriptor to become available. Only retire TDA's
     586   * if there are no more free buffers to minimize TX latency. Retire TDA'a
     587   * on the way out.
     588   */
     589
     590  while (sc->tdaHead->next->status != 0) {
     591 
     592  /*
     593   * Free up transmit descriptors
     594   */
     595    sonic_retire_tda (sc);
     596
     597    if (sc->tdaHead->next->status == 0)
     598      break;
     599
    568600#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
    569     puts( "Wait for more TDAs" );
    570 #endif
    571 
    572     /*
    573      * Clear old events.
    574      */
    575     (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
    576 
    577     /*
    578      * Wait for transmit descriptor to become available.
    579      * Note that the transmit descriptors are checked
    580      * *before* * entering the wait loop -- this catches
    581      * the possibility that a transmit descriptor became
    582      * available between the `if' the started this block,
    583      * and the clearing of the interrupt status register.
    584      */
    585     sonic_retire_tda (sc);
    586     while (sc->tdaActiveCount == sc->tdaCount) {
    587       rtems_event_set events;
    588 
    589 #if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
    590       printf("blocking until TDAs are available\n");
     601    printf("blocking until TDAs are available\n");
    591602#endif
    592603      /*
    593        * Enable transmitter interrupts.
     604       * Enable PINT interrupts.
     605    sonic_clear_interrupts( sc, ISR_PINT );
     606    sonic_enable_interrupts( sc, IMR_PINTEN );
    594607       */
    595       sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
    596608
    597609      /*
    598        * Wait for interrupt
     610       * Wait for PINT TX interrupt. Every fourth TX buffer will raise PINT.
    599611       */
    600       rtems_bsdnet_event_receive (INTERRUPT_EVENT,
     612    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
    601613            RTEMS_WAIT|RTEMS_EVENT_ANY,
    602614            RTEMS_NO_TIMEOUT,
    603615            &events);
    604       (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
    605       sonic_retire_tda (sc);
    606     }
     616    sonic_disable_interrupts( sc, IMR_PINTEN );
     617    sonic_retire_tda (sc);
    607618  }
    608619
     
    686697  if ( sc->tdaHead->frag_count )
    687698    *sc->tdaHead->linkp &= ~TDA_LINK_EOL;
    688   sc->tdaActiveCount++;
    689699  sc->tdaHead = tdp;
    690700
    691 /* XXX not in KA9Q */
    692   sonic_enable_interrupts( sc, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
    693   (*sc->write_register)( rp, SONIC_REG_CR, CR_TXP );
     701  /* Start transmission */
     702
     703  sonic_command(sc, CR_TXP );
     704
     705  /*
     706   * Free up transmit descriptors on the way out.
     707   */
     708  sonic_retire_tda (sc);
    694709}
    695710
     
    837852       * Restart reception
    838853       */
    839       (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBAE );
    840       (*sc->write_register)( rp, SONIC_REG_CR, CR_RXEN );
     854      sonic_clear_interrupts( sc, ISR_RBAE );
     855      sonic_command( sc, CR_RXEN );
    841856    }
    842 
    843     /*
    844      * Clear old packet-received events.
    845      */
    846     (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PKTRX );
    847857
    848858    /*
     
    934944#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
    935945      sonic_print_rx_descriptor( rdp );
    936 #endif
     946      if ((LSW(rdp->mbufp->m_data) != rdp->pkt_lsw)
     947       || (MSW(rdp->mbufp->m_data) != rdp->pkt_msw))
     948        printf ("SONIC RDA/RRA %p, %08x\n",rdp->mbufp->m_data,(rdp->pkt_msw << 16) |
     949        (rdp->pkt_lsw & 0x0ffff));
     950#endif
     951      rdp->byte_count &= 0x0ffff;    /* ERC32 pollutes msb of byte_count */
    937952      m = rdp->mbufp;
    938953      m->m_len = m->m_pkthdr.len = rdp->byte_count -
     
    942957      m->m_data += sizeof(struct ether_header);
    943958 
     959#ifdef CPU_U32_FIX
     960      ipalign(m);       /* Align packet on 32-bit boundary */
     961#endif
     962
    944963#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_RX_MBUFS)
    945964      Dump_Buffer( (void *) eh, sizeof(struct ether_header) );
     
    948967
    949968      /* printf( "ether_input %p\n", m ); */
     969      /*
     970      printf( "pkt %p, seq %04x, mbuf %p, m_data %p\n", rdp, rdp->seq_no, m, m->m_data );
     971      printf( "%u, %u\n", ((int*)m->m_data)[6], ((int*)m->m_data)[7]);
     972      */
    950973      ether_input (ifp, eh, m);
     974      /*
     975      */
    951976
    952977      /*
     
    9961021       */
    9971022      if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBE)
    998         (*sc->write_register)( rp, SONIC_REG_ISR, ISR_RBE );
     1023      sonic_clear_interrupts( sc, ISR_RBE );
    9991024    }
    10001025    else {
     
    10171042
    10181043    /*
    1019      * Move to next receive descriptor
    1020      */
    1021 
     1044     * Move to next receive descriptor and update EOL
     1045     */
     1046
     1047    rdp->link |= RDA_LINK_EOL;
    10221048    rdp->in_use = RDA_FREE;
     1049    sc->rdp_last->link &= ~RDA_LINK_EOL;
     1050    sc->rdp_last = rdp;
    10231051    rdp = rdp->next;
    1024     rdp->link &= ~RDA_LINK_EOL;
    10251052
    10261053  }
     
    10591086   */
    10601087
    1061   if ( (*sc->read_register)( rp, SONIC_REG_SR ) < SONIC_REVISION_C ) {
     1088  if ( (*sc->read_register)( rp, SONIC_REG_SR ) <= SONIC_REVISION_B ) {
    10621089    rtems_fatal_error_occurred( 0x0BADF00D );  /* don't eat this part :) */
    10631090  }
     
    10711098   */
    10721099
    1073   sc->tdaActiveCount = 0;
    10741100  sc->tdaTail = sonic_allocate(sc->tdaCount * sizeof *tdp);
    10751101#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
     
    10881114
    10891115/* XXX not used by the BSD drivers
     1116    tdp->frag[0].frag_link = LSW(tdp + 1);
    10901117*/
    1091     if (i & 1)
     1118    if (i & 3)
    10921119      tdp->pkt_config = TDA_CONFIG_PINT;
    10931120
    1094     tdp->frag_count        = 0;
    1095     tdp->frag[0].frag_link = LSW(tdp + 1);
    1096     tdp->link_pad          = LSW(tdp + 1) | TDA_LINK_EOL;
    1097     tdp->linkp             = &((tdp + 1)->frag[0].frag_link);
    1098     tdp->next              = (TransmitDescriptor_t *)(tdp + 1);
     1121    tdp->status         = 0;
     1122    tdp->frag_count     = 0;
     1123    tdp->link_pad       = LSW(tdp + 1) | TDA_LINK_EOL;
     1124    tdp->linkp          = &((tdp + 1)->frag[0].frag_link);
     1125    tdp->next           = (TransmitDescriptor_t *)(tdp + 1);
    10991126#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
    11001127    sonic_print_tx_descriptor( tdp );
     
    11431170  ordp->next   = sc->rda;
    11441171  ordp->link   = LSW(sc->rda) | RDA_LINK_EOL;
    1145   sc->rdp_last = rdp;
     1172  sc->rdp_last = ordp;
    11461173 
    11471174  /*
     
    13201347        (*sc->read_register)( rp, SONIC_REG_CAP0 ),
    13211348        (*sc->read_register)( rp, SONIC_REG_CE ));
    1322 #endif
    13231349
    13241350  (*sc->write_register)( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */
     
    13371363    rtems_panic ("SONIC LCAM");
    13381364  }
     1365#endif
    13391366
    13401367  (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);
     
    13871414     * Start driver tasks
    13881415     */
     1416    sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
    13891417    sc->txDaemonTid = rtems_bsdnet_newproc ("SNtx", 4096, sonic_txDaemon, sc);
    1390     sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
    13911418  }
    13921419
     
    14091436   * Enable receiver and transmitter
    14101437   */
    1411   /* (*sc->write_register)( rp, SONIC_REG_IMR, 0 ); */
    1412   sonic_enable_interrupts( sc,
    1413         (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) | (IMR_PRXEN | IMR_RBAEEN) );
    1414 
    1415   (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */ CR_RXEN);
     1438  sonic_enable_interrupts( sc, IMR_TXEREN | (IMR_PRXEN | IMR_RBAEEN) );
     1439  sonic_command( sc, CR_RXEN );
    14161440}
    14171441
Note: See TracChangeset for help on using the changeset viewer.