Changeset 9142bf39 in rtems


Ignore:
Timestamp:
Oct 20, 2000, 12:57:46 PM (19 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
b0a26ddd
Parents:
8327c5c
Message:

2000-10-20 Dmitry Kargapolov <dk@…>

  • ne2000/ne2000.c: Fix some errors in the driver.
  1. There was no sufficient check of data in ethernet header. The code in ne_rx_daemon() was:

inport_word (dport, len);
...
len -= 4;

...

if (len > 0)

ne_read_data (sc, startaddr, len, p);

Unfortunately, sometimes my NIC gave me too big len value,
the result was memory override. To fix this, I added ethernet
header data checking.

  1. The way overrides were serviced was not good. It was complex but sometimes did not provide reliable continuing of NIC working. I had the situation of an endless loop in ne_check_status() after override processing.
  1. There was conceptual error of porting. The old method of overrides curing was ported from the OS-s, where override-processing did start immediately. But RTEMS-version uses events, and cleaning of the overrides can start later.

I selected the way of ne2000 programming that is used
in freebsd kernel (v4.0).

Because of both problems, incorrect data in header of raw packet
and receiver override, it went through ne_reset() and fully
reset the ne2000.

So, in summary

  • added detecting of the incorrect data in ethernet header;
  • replaced handling of receiver overrides with new scheme, via resetting of NIC, this method is used also in case of invalid header detecting.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c

    r8327c5c r9142bf39  
    2424 *  code does make it possible, by changing NE_TX_BUFS, although that
    2525 *  would of course reduce the number of receive buffers.
    26  * 
     26 *
    2727 *  I suspect that the wd80x3 driver would benefit slightly from copying
    2828 *  the multiple transmit buffer code.  However, I have no way to test
     
    3030 */
    3131
     32#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
     33
    3234#include <bsp.h>
    3335#include <wd80x3.h>
     
    6062
    6163/* #define DEBUG_NE2000 */
     64/* #define DEBUG_NE */
    6265
    6366/* We expect to be able to read a complete packet into an mbuf.  */
     
    7174
    7275/* Minimum size of Ethernet packet.  */
    73 #define ET_MINLEN 60
     76#define ET_MINLEN 60
    7477
    7578/* The number of NE2000 devices supported by this driver.  */
    7679
    77 #define NNEDRIVER       1
     80#define NNEDRIVER 1
    7881
    7982/* RTEMS event number used by the interrupt handler to signal the
     
    187190static struct ne_softc ne_softc[NNEDRIVER];
    188191
     192/*
     193 * receive ring descriptor
     194 *
     195 * The National Semiconductor DS8390 Network interface controller uses
     196 * the following receive ring headers.  The way this works is that the
     197 * memory on the interface card is chopped up into 256 bytes blocks.
     198 * A contiguous portion of those blocks are marked for receive packets
     199 * by setting start and end block #'s in the NIC.  For each packet that
     200 * is put into the receive ring, one of these headers (4 bytes each) is
     201 * tacked onto the front. The first byte is a copy of the receiver status
     202 * register at the time the packet was received.
     203 */
     204struct ne_ring
     205{
     206        unsigned char rsr;    /* receiver status */
     207        unsigned char next;   /* pointer to next packet */
     208        unsigned short count; /* bytes in packet (length + 4)   */
     209};
     210
    189211/* Forward declarations to avoid warnings */
    190212
     213static void ne_init_irq_handler (int irno);
    191214static void ne_stop (struct ne_softc *sc);
     215static void ne_stop_hardware (struct ne_softc *sc);
    192216static void ne_init (void *arg);
     217static void ne_init_hardware (struct ne_softc *sc);
     218
     219static void ne_reset(struct ne_softc *sc);
     220#ifdef DEBUG_NE
     221static void ne_dump(struct ne_softc *sc);
     222#endif
    193223
    194224/* Find the NE2000 device which is attached at a particular interrupt
     
    203233    {
    204234      if (ne_softc[i].irno == irno
    205           && ne_softc[i].arpcom.ac_if.if_softc != NULL)
    206         return &ne_softc[i];
     235          && ne_softc[i].arpcom.ac_if.if_softc != NULL)
     236        return &ne_softc[i];
    207237    }
    208238
     
    227257
    228258  if (sc->byte_transfers)
    229     while (len > 0) {
    230       unsigned char d;
    231      
    232       inport_byte (dport, d);
     259  {
     260    unsigned char d;
     261    while (len > 0)
     262    {
     263      inport_byte(dport, d);
    233264      *p++ = d;
    234265      len--;
    235266    }
     267  }
    236268  else  /* word transfers */
    237     while (len > 0) {
    238       unsigned short d;
    239      
    240       inport_word (dport, d);
     269  {
     270    unsigned short d;
     271    while (len > 1)
     272    {
     273      inport_word(dport, d);
    241274      *p++ = d;
    242275      *p++ = d >> 8;
    243276      len -= 2;
    244277    }
     278    if (len)
     279    {
     280      inport_word(dport, d);
     281      *p++ = d;
     282    }
     283  }
    245284
    246285  outport_byte (port + ISR, MSK_RDC);
     
    252291
    253292static void
    254 ne_check_status (struct ne_softc *sc)
    255 {
     293ne_check_status (struct ne_softc *sc, int from_irq_handler)
     294{
     295  struct ifnet *ifp = &sc->arpcom.ac_if;
    256296  unsigned int port = sc->port;
    257297  unsigned char status;
     
    264304     Realtek 8019AS chip).  */
    265305
    266   while (1) {
     306  /* int count = 0; */
     307  while (1)
     308  {
    267309    inport_byte (port + ISR, status);
    268310    if (status == 0)
    269311      break;
    270312
     313    /* ack */
     314    outport_byte (port + ISR, status);
     315
    271316#ifdef DEBUG_NE2000
    272317    printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status,
    273             i8259s_cache & (1 << sc->irno) ? "no" : "yes",
    274             i8259s_cache);
     318            i8259s_cache & (1 << sc->irno) ? "no" : "yes",
     319            i8259s_cache);
    275320#endif
    276321
    277322    /* Check for incoming packet overwrite.  */
    278     if (status & MSK_OVW) {
    279       unsigned char status2;
    280 
     323    if (status & MSK_OVW)
     324    {
     325      ifp->if_timer = 0;
     326#ifdef DEBUG_NE
     327      printk("^");
     328#endif
    281329      ++sc->stats.overruns;
    282       outport_byte (port + CMDR, MSK_PG0 | MSK_STP | MSK_RD2);
    283       Wait_X_ms (2);
    284       outport_byte (port + RBCR0, 0);
    285       outport_byte (port + RBCR1, 0);
    286       inport_byte (port + ISR, status2);
    287       status |= status2 & (MSK_PTX | MSK_TXE);
    288       outport_byte (port + TCR, MSK_LOOP);
    289       outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
    290       sc->overrun = 1;
    291       if ((status & (MSK_PTX | MSK_TXE)) == 0)
    292         sc->resend = 1;
    293       rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
     330      ne_reset(sc);
     331      /* Reenable device interrupts.  */
     332      if (from_irq_handler)
     333        outport_byte(port + IMR, NE_INTERRUPTS);
     334      return;
    294335    }
    295336
    296337    /* Check for transmitted packet.  The transmit daemon may now be
    297338       able to send another packet to the device.  */
    298     if ((status & (MSK_PTX | MSK_TXE)) != 0) {
     339    if ((status & (MSK_PTX | MSK_TXE)) != 0)
     340    {
     341      ifp->if_timer = 0;
    299342      ++sc->stats.tx_acks;
    300       outport_byte (port + ISR, status & (MSK_PTX | MSK_TXE));
    301343      --sc->inuse;
    302344      sc->transmitting = 0;
    303345      if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
    304         rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
     346        rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
    305347    }
    306348
    307349    /* Check for received packet.  */
    308     if ((status & (MSK_PRX | MSK_RXE)) != 0) {
     350    if ((status & (MSK_PRX | MSK_RXE)) != 0)
     351    {
    309352      ++sc->stats.rx_acks;
    310       outport_byte (port + ISR, status & (MSK_PRX | MSK_RXE));
    311353      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
    312354    }
    313355
    314356    /* Check for counter change.  */
    315     if ((status & MSK_CNT) != 0) {
     357    if ((status & MSK_CNT) != 0)
     358    {
    316359      unsigned char add;
    317 
    318360      inport_byte (port + CNTR0, add);
    319361      sc->stats.rx_frame_errors += add;
     
    322364      inport_byte (port + CNTR2, add);
    323365      sc->stats.rx_missed_errors += add;
    324       outport_byte (port + ISR, MSK_CNT);
    325     }
     366    }
     367
     368    break;
     369    /* if (++count >= 1000)
     370    {
     371      printk("status: %x\n", status);
     372      ne_reset(sc);
     373      if (from_irq_handler)
     374        outport_byte(port + IMR, NE_INTERRUPTS);
     375      return;
     376    } */
    326377  }
    327378
     
    342393  ++sc->stats.interrupts;
    343394
    344   ne_check_status (sc);
     395#ifdef DEBUG_NE
     396  printk("!");
     397#endif
     398  ne_check_status(sc, 1);
    345399}
    346400
     
    352406  struct ne_softc *sc;
    353407
    354 #ifdef DEBUG_NE2000
    355   printk ("ne_interrupt_on\n");
     408#ifdef DEBUG_NE
     409  printk ("ne_interrupt_on()\n");
    356410#endif
    357411  sc = ne_device_for_irno (irq->name);
     
    367421  struct ne_softc *sc;
    368422
    369 #ifdef DEBUG_NE2000
    370   printk ("ne_interrupt_off\n");
     423#ifdef DEBUG_NE
     424  printk ("ne_interrupt_off()\n");
    371425#endif
    372426  sc = ne_device_for_irno (irq->name);
     
    390444  unsigned int port = sc->port;
    391445  int i;
    392   rtems_irq_connect_data irq;
    393446
    394447#ifdef DEBUG_NE2000
    395   printk ("ne_init_hardware\n");
     448  printk ("ne_init_hardware()\n");
    396449#endif
    397450
    398451  /* Initialize registers.  */
    399452
     453  /* Set interface for page 0, Remote DMA complete, Stopped */
    400454  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
    401455
    402   if (sc->byte_transfers) {
     456  /* Set FIFO threshold to 8, No auto-init Remote DMA, byte order=80x86 */
     457  /* byte-wide DMA xfers */
     458  if (sc->byte_transfers)
    403459    outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
    404   }
    405   else {
     460  /* word-wide DMA xfers */
     461  else
    406462    outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
    407   }
    408 
     463
     464  /* Clear Remote Byte Count Registers */
    409465  outport_byte (port + RBCR0, 0);
    410466  outport_byte (port + RBCR1, 0);
     467
     468  /* For the moment, don't store incoming packets in memory. */
    411469  outport_byte (port + RCR, MSK_MON);
     470
     471  /* Place NIC in internal loopback mode */
    412472  outport_byte (port + TCR, MSK_LOOP);
     473
     474  /* Initialize transmit/receive (ring-buffer) Page Start */
     475  outport_byte (port + TPSR, NE_FIRST_TX_PAGE);
     476  outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
     477
     478  /* Initialize Receiver (ring-buffer) Page Stop and Boundry */
     479  outport_byte (port + PSTOP, NE_STOP_PAGE);
     480  outport_byte (port + BNRY, NE_STOP_PAGE - 1);
     481
     482  /* Clear all interrupts */
     483  outport_byte (port + ISR, 0xff);
     484  /* Disable all interrupts */
    413485  outport_byte (port + IMR, 0);
    414   outport_byte (port + ISR, 0xff);
    415   outport_byte (port + PSTOP, NE_STOP_PAGE);
    416   outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
    417   outport_byte (port + BNRY, NE_STOP_PAGE - 1);
     486
     487  /* Program Command Register for page 1 */
     488  outport_byte (port + CMDR, MSK_PG1 | MSK_RD2 | MSK_STP);
    418489
    419490  /* Set the Ethernet hardware address.  */
    420 
    421   outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
    422491  for (i = 0; i < ETHER_ADDR_LEN; ++i)
    423492    outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
    424493
    425 #ifdef DEBUG_NE2000
    426   printk ("Using ethernet address: ");
    427   for (i = 0; i < ETHER_ADDR_LEN; ++i)
    428     printk("%x ",sc->arpcom.ac_enaddr[i]);
    429   printk ("\n");
    430 #endif
     494  /* Set Current Page pointer to next_packet */
     495  outport_byte (port + CURR, NE_FIRST_RX_PAGE);
    431496
    432497  /* Clear the multicast address.  */
     
    434499    outport_byte (port + MAR + i, 0);
    435500
    436   outport_byte (port + CURR, NE_FIRST_RX_PAGE);
    437 
    438   outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
    439 
    440   /* Put the device on line.  */
    441   outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
    442 
    443   /* Set up interrupts.  */
    444 
    445   irq.name = sc->irno;
    446   irq.hdl = ne_interrupt_handler;
     501  /* Set page 0 registers */
     502  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
     503
     504  /* accept broadcast */
     505  outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0));
     506
     507  /* Start interface */
     508  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
     509
     510  /* Take interface out of loopback */
     511  outport_byte (port + TCR, 0);
     512}
     513
     514/* Set up interrupts.
     515*/
     516static void
     517ne_init_irq_handler(int irno)
     518{
     519  rtems_irq_connect_data irq;
     520
     521#ifdef DEBUG_NE
     522  printk("ne_init_irq_handler(%d)\n", irno);
     523#endif
     524  irq.name = irno;
     525  irq.hdl = (rtems_irq_hdl)ne_interrupt_handler;
    447526  irq.on = ne_interrupt_on;
    448527  irq.off = ne_interrupt_off;
    449528  irq.isOn = ne_interrupt_is_on;
    450529
    451   if (! BSP_install_rtems_irq_handler (&irq))
    452     rtems_panic ("Can't attach NE interrupt handler for irq %d.\n",
    453                  sc->irno);
    454 
    455   /* Prepare to receive packets.  */
    456 
    457   outport_byte (port + TCR, 0);
    458   outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0));
     530  if (!BSP_install_rtems_irq_handler (&irq))
     531    rtems_panic ("Can't attach NE interrupt handler for irq %d\n", irno);
    459532}
    460533
    461534/* The NE2000 packet receive daemon.  This task is started when the
    462535   NE2000 driver is initialized.  */
     536
     537#ifdef DEBUG_NE
     538static int ccc = 0; /* experinent! */
     539#endif
    463540
    464541static void
     
    468545  struct ifnet *ifp = &sc->arpcom.ac_if;
    469546  unsigned int port = sc->port;
    470   unsigned int dport = port + DATAPORT;
    471 
    472   while (1) {
     547
     548  while (1)
     549  {
    473550    rtems_event_set events;
    474551
     
    476553       packet ready to receive.  */
    477554    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
    478                                 RTEMS_WAIT | RTEMS_EVENT_ANY,
    479                                 RTEMS_NO_TIMEOUT,
    480                                 &events);
     555                                RTEMS_WAIT | RTEMS_EVENT_ANY,
     556                                RTEMS_NO_TIMEOUT,
     557                                &events);
    481558
    482559    /* Don't let the device interrupt us now.  */
    483560    outport_byte (port + IMR, 0);
    484561
    485     while (1) {
     562    while (1)
     563    {
    486564      unsigned char startpage, currpage;
    487       unsigned short statnext, len;
    488       int next;
     565      unsigned short len;
     566      unsigned char next, stat, cnt1, cnt2;
    489567      struct mbuf *m;
    490568      unsigned char *p;
     
    492570      int toend;
    493571      struct ether_header *eh;
     572      struct ne_ring hdr; /* ring buffer header */
     573      int reset;
    494574
    495575      inport_byte (port + BNRY, startpage);
     
    501581      ++startpage;
    502582      if (startpage >= NE_STOP_PAGE)
    503         startpage = NE_FIRST_RX_PAGE;
     583        startpage = NE_FIRST_RX_PAGE;
    504584
    505585      if (startpage == currpage)
    506         break;
     586        break;
    507587
    508588#ifdef DEBUG_NE2000
    509589      printk ("ne_rx_daemon: start page %x; current page %x\n",
    510               startpage, currpage);
    511 #endif
    512 
    513       /* Read the buffer header.  This is 1 byte receive status, 1
    514          byte page of next buffer, 2 bytes length.  */
    515       outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
    516       outport_byte (port + RBCR0, 4);
    517       outport_byte (port + RBCR1, 0);
    518       outport_byte (port + RSAR0, 0);
    519       outport_byte (port + RSAR1, startpage);
    520       outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
    521 
    522       if (sc->byte_transfers) {
    523         unsigned char data;
    524 
    525         inport_byte (dport, data);  /* Throw away status  */
    526         inport_byte (dport, data);
    527         next = data;
    528 
    529         inport_byte (dport, data);
    530         len = data;
    531         inport_byte (dport, data);
    532         len |= data << 8;
     590              startpage, currpage);
     591#endif
     592
     593      reset = 0;
     594
     595      /* Read the buffer header */
     596      startaddr = startpage * NE_PAGE_SIZE;
     597      ne_read_data(sc, startaddr, sizeof(hdr), (unsigned char *)&hdr);
     598      next = hdr.next;
     599      if (next >= NE_STOP_PAGE)
     600        next = NE_FIRST_RX_PAGE;
     601
     602      /* check packet length */
     603      len = hdr.count;
     604      if (currpage < startpage)
     605        cnt1 = currpage + (NE_STOP_PAGE - NE_FIRST_RX_PAGE) - startpage;
     606      else
     607        cnt1 = currpage - startpage;
     608      cnt2 = len / NE_PAGE_SIZE;
     609      if (len % NE_PAGE_SIZE)
     610        cnt2++;
     611      if (cnt1 < cnt2)
     612      {
     613#ifdef DEBUG_NE
     614        printk("(%x<%x:%x)", cnt1, cnt2, len);
     615/*
     616        printk("start page 0x%x; current page 0x%x\n",
     617                startpage, currpage);
     618        printk("cnt1 < cnt2 (0x%x, 0x%x); len 0x%x\n",
     619                cnt1, cnt2, len);
     620*/
     621#endif
     622        reset = 1;
    533623      }
    534       else {                        /* Word transfers  */
    535         inport_word (dport, statnext);
    536         inport_word (dport, len);
    537 
    538         next = statnext >> 8;
     624      if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
     625          len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
     626          len > MCLBYTES)
     627      {
     628#ifdef DEBUG_NE
     629        printk("(%x)", len);
     630/*
     631        printk("start page 0x%x; current page 0x%x\n",
     632                startpage, currpage);
     633        printk("len out of range: 0x%x\n", len);
     634        printk("stat: 0x%x, next: 0x%x\n", hdr.rsr, hdr.next);
     635*/
     636#endif
     637        reset = 1;
    539638      }
    540 
    541       outport_byte (port + ISR, MSK_RDC);
    542 
    543       if (next >= NE_STOP_PAGE)
    544         next = NE_FIRST_RX_PAGE;
     639#ifdef DEBUG_NE
     640      if (++ccc == 100)
     641      { ccc = 0; reset = 1;
     642        printk("T");
     643      }
     644#endif
     645
     646      /* reset interface */
     647      if (reset)
     648      {
     649        ne_reset(sc);
     650        goto Next;
     651      }
     652
     653      stat = hdr.rsr;
    545654
    546655      /* The first four bytes of the length are the buffer header.  */
    547       len -= 4;
    548       startaddr = startpage * NE_PAGE_SIZE + 4;
     656      len -= sizeof(struct ne_ring);
     657      startaddr += sizeof(struct ne_ring);
    549658
    550659      MGETHDR (m, M_WAIT, MT_DATA);
     
    553662
    554663      p = mtod (m, unsigned char *);
    555       m->m_len = m->m_pkthdr.len = len - sizeof (struct ether_header);
     664      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
    556665
    557666      toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
    558       if (toend < len) {
    559         ne_read_data (sc, startaddr, toend, p);
    560         p += toend;
    561         len -= toend;
    562         startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
     667      if (toend < len)
     668      {
     669        ne_read_data (sc, startaddr, toend, p);
     670        p += toend;
     671        len -= toend;
     672        startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
    563673      }
    564674
    565675      if (len > 0)
    566         ne_read_data (sc, startaddr, len, p);
     676        ne_read_data (sc, startaddr, len, p);
    567677
    568678      eh = mtod (m, struct ether_header *);
    569679      m->m_data += sizeof (struct ether_header);
     680
     681#ifdef DEBUG_NE
     682  /* printk("[r%d]", hdr.count - sizeof(hdr)); */
     683  printk("<");
     684#endif
    570685      ether_input (ifp, eh, m);
    571 
    572686      ++sc->stats.rx_packets;
    573687
     
    579693      outport_byte (port + TCR, 0);
    580694      if (sc->resend)
    581         outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
     695        outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
    582696      sc->resend = 0;
    583697      sc->overrun = 0;
    584698    }
    585699
     700  Next:
    586701    /* Reenable device interrupts.  */
    587702    outport_byte (port + IMR, NE_INTERRUPTS);
     
    600715  unsigned char leftover_data;
    601716  int timeout;
     717  int send_cnt = 0;
    602718
    603719#ifdef DEBUG_NE2000
     
    617733  outport_byte (port + RSAR0, 0);
    618734  outport_byte (port + RSAR1,
    619                 NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
     735                NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
    620736
    621737  /* Set up the write.  */
     
    646762      --len;
    647763      outport_word (dport, leftover_data | (next << 8));
     764      send_cnt += 2;
    648765      leftover = 0;
    649766    }
    650767
    651     /* If using byte transfers, len always ends up as zero so 
     768    /* If using byte transfers, len always ends up as zero so
    652769       there are no leftovers. */
    653770
    654771    if (sc->byte_transfers)
    655772      while (len > 0) {
    656         outport_byte (dport, *data++);
    657         len--;
     773        outport_byte (dport, *data++);
     774        len--;
    658775      }
    659776    else
    660777      while (len > 1) {
    661         outport_word (dport, data[0] | (data[1] << 8));
    662         data += 2;
    663         len -= 2;
     778        outport_word (dport, data[0] | (data[1] << 8));
     779        data += 2;
     780        len -= 2;
     781        send_cnt += 2;
    664782      }
    665783
    666784    if (len > 0)
    667785      {
    668         leftover = 1;
    669         leftover_data = *data++;
     786        leftover = 1;
     787        leftover_data = *data++;
    670788      }
    671789  }
    672790
    673791  if (leftover)
     792  {
    674793    outport_word (dport, leftover_data);
    675 
     794    send_cnt += 2;
     795  }
     796
     797#ifdef DEBUG_NE
     798  /* printk("{l%d|%d}", send_cnt, sc->nextavail); */
     799  printk("v");
     800#endif
    676801  m_freem (mhold);
    677802
     
    686811#ifdef DEBUG_NE2000
    687812      if ((status &~ MSK_RDC) != 0)
    688         printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
    689                 status);
     813        printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
     814                status);
    690815#endif
    691816
    692817      if ((status & MSK_RDC) != 0) {
    693         outport_byte (port + ISR, MSK_RDC);
    694         break;
     818        outport_byte (port + ISR, MSK_RDC);
     819        break;
    695820      }
    696821    }
     
    710835ne_transmit (struct ne_softc *sc)
    711836{
     837  struct ifnet *ifp = &sc->arpcom.ac_if;
    712838  unsigned int port = sc->port;
    713839  int len;
     
    727853  outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
    728854
     855#ifdef DEBUG_NE
     856  /* printk("{s%d|%d}", len, sc->nextsend); */
     857  printk(">");
     858#endif
    729859  ++sc->nextsend;
    730860  if (sc->nextsend == NE_TX_BUFS)
     
    732862
    733863  ++sc->stats.tx_packets;
     864
     865  /* set watchdog timer */
     866  ifp->if_timer = 2;
    734867}
    735868
     
    750883       room for another packet in the device memory.  */
    751884    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
    752                                 RTEMS_EVENT_ANY | RTEMS_WAIT,
    753                                 RTEMS_NO_TIMEOUT,
    754                                 &events);
     885                                RTEMS_EVENT_ANY | RTEMS_WAIT,
     886                                RTEMS_NO_TIMEOUT,
     887                                &events);
    755888
    756889#ifdef DEBUG_NE2000
     
    772905         uploaded a packet, tell the device to transmit it.  */
    773906      if (! sc->transmitting && sc->inuse > 0) {
    774         sc->transmitting = 1;
    775         ne_transmit (sc);
     907        sc->transmitting = 1;
     908        ne_transmit (sc);
    776909      }
    777910
    778911      /* If we don't have any more buffers to send, quit now.  */
    779912      if (ifp->if_snd.ifq_head == NULL) {
    780         ifp->if_flags &= ~IFF_OACTIVE;
    781         break;
     913        ifp->if_flags &= ~IFF_OACTIVE;
     914        break;
    782915      }
    783916
     
    785918         available, quit until a buffer has been transmitted.  */
    786919      if (sc->inuse >= NE_TX_BUFS)
    787         break;
     920        break;
    788921
    789922      ++sc->inuse;
     
    791924      IF_DEQUEUE (&ifp->if_snd, m);
    792925      if (m == NULL)
    793         panic ("ne_tx_daemon");
     926        panic ("ne_tx_daemon");
    794927
    795928      ne_loadpacket (sc, m);
     
    797930      /* Check the device status.  It may have finished transmitting
    798931         the last packet.  */
    799       ne_check_status (sc);
     932      ne_check_status(sc, 0);
    800933    }
    801934
     
    812945  struct ne_softc *sc = ifp->if_softc;
    813946
     947#ifdef DEBUG_NE
     948  printk("S");
     949#endif
    814950  /* Tell the transmit daemon to wake up and send a packet.  */
    815951  rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
     
    825961  struct ifnet *ifp = &sc->arpcom.ac_if;
    826962
    827   if (sc->tx_daemon_tid == 0) {
     963#ifdef DEBUG_NE
     964  printk("ne_init()\n");
     965  ne_dump(sc);
     966#endif
     967
     968  /* only once... */
     969  if (sc->tx_daemon_tid == 0)
     970  {
    828971    sc->inuse = 0;
    829972    sc->nextavail = 0;
     
    835978    sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
    836979    sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
     980
     981    /* install rtems irq handler */
     982    ne_init_irq_handler(sc->irno);
    837983  }
    838984
     
    844990static void
    845991ne_stop (struct ne_softc *sc)
     992{
     993  sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
     994
     995  ne_stop_hardware(sc);
     996
     997  sc->inuse = 0;
     998  sc->nextavail = 0;
     999  sc->nextsend = 0;
     1000  sc->transmitting = 0;
     1001  sc->overrun = 0;
     1002  sc->resend = 0;
     1003}
     1004
     1005static void
     1006ne_stop_hardware (struct ne_softc *sc)
    8461007{
    8471008  unsigned int port = sc->port;
    8481009  int i;
    849 
    850   sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
    8511010
    8521011  /* Stop everything.  */
     
    8601019      inport_byte (port + ISR, status);
    8611020      if ((status & MSK_RST) != 0)
    862         break;
    863     }
    864 
    865   sc->inuse = 0;
    866   sc->nextavail = 0;
    867   sc->nextsend = 0;
    868   sc->transmitting = 0;
    869 }
     1021        break;
     1022    }
     1023}
     1024
     1025/* reinitializing interface
     1026*/
     1027static void
     1028ne_reset(struct ne_softc *sc)
     1029{
     1030  ne_stop(sc);
     1031  ne_init_hardware(sc);
     1032  sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
     1033  sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
     1034#ifdef DEBUG_NE
     1035  printk("*");
     1036#endif
     1037}
     1038
     1039#ifdef DEBUG_NE
     1040/* show anything about ne
     1041*/
     1042static void
     1043ne_dump(struct ne_softc *sc)
     1044{
     1045  int i;
     1046  printk("\nne configuration:\n");
     1047  printk("ethernet addr:");
     1048  for (i=0; i<ETHER_ADDR_LEN; i++)
     1049    printk(" %x", sc->arpcom.ac_enaddr[i]);
     1050  printk("\n");
     1051  printk("irq = %d\n", sc->irno);
     1052  printk("port = 0x%x\n", sc->port);
     1053  printk("accept_broadcasts = %d\n", sc->accept_broadcasts);
     1054  printk("byte_transfers = %d\n", sc->byte_transfers);
     1055}
     1056#endif
    8701057
    8711058/* Show NE2000 interface statistics.  */
     
    9331120}
    9341121
     1122/*
     1123 * Device timeout/watchdog routine. Entered if the device neglects to
     1124 *      generate an interrupt after a transmit has been started on it.
     1125 */
     1126static void
     1127ne_watchdog(struct ifnet *ifp)
     1128{
     1129  struct ne_softc *sc = ifp->if_softc;
     1130
     1131  printk("ne2000: device timeout\n");
     1132    ifp->if_oerrors++;
     1133
     1134  ne_reset(sc);
     1135}
     1136
     1137static void
     1138print_byte(unsigned char b)
     1139{
     1140  printk("%x%x", b >> 4, b & 0x0f);
     1141}
     1142
    9351143/* Attach an NE2000 driver to the system.  */
    9361144
    9371145int
    938 rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config)
     1146rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
    9391147{
    9401148  int i;
     
    9421150  struct ifnet *ifp;
    9431151  int mtu;
     1152
     1153  /* dettach ... */
     1154  if (!attach)
     1155    return 0;
    9441156
    9451157  /* Find a free driver.  */
     
    9601172
    9611173  /* Check whether we do byte-wide or word-wide transfers.  */
    962  
     1174
    9631175#ifdef NE2000_BYTE_TRANSFERS
    9641176  sc->byte_transfers = TRUE;
     
    9921204  if (config->hardware_address != NULL)
    9931205    memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
    994             ETHER_ADDR_LEN);
     1206            ETHER_ADDR_LEN);
    9951207  else
    9961208    {
     
    10031215
    10041216      if (sc->byte_transfers) {
    1005         outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
     1217        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
    10061218      }
    10071219      else {
    1008         outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
     1220        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
    10091221      }
    10101222
     
    10211233
    10221234      for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
    1023         sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
     1235        sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
    10241236    }
    10251237
     
    10321244  ifp->if_init = ne_init;
    10331245  ifp->if_ioctl = ne_ioctl;
     1246  ifp->if_watchdog = ne_watchdog;
    10341247  ifp->if_start = ne_start;
    10351248  ifp->if_output = ether_output;
     
    10431256  ether_ifattach (ifp);
    10441257
     1258  printk("network device '%s' <", config->name);
     1259  print_byte(sc->arpcom.ac_enaddr[0]);
     1260  for (i=1; i<ETHER_ADDR_LEN; i++)
     1261  { printk(":");
     1262    print_byte(sc->arpcom.ac_enaddr[i]);
     1263  }
     1264  printk("> initialized on port 0x%x, irq %d\n", sc->port, sc->irno);
     1265
    10451266  return 1;
    10461267}
     1268
Note: See TracChangeset for help on using the changeset viewer.