OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [eth.c] - Diff between revs 434 and 436

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 434 Rev 436
Line 267... Line 267...
        }
        }
 
 
      /* stay in this state if (TXEN && !READY) */
      /* stay in this state if (TXEN && !READY) */
      break;
      break;
    case ETH_TXSTATE_READFIFO:
    case ETH_TXSTATE_READFIFO:
      if (eth->tx.bytes_sent < eth->tx.packet_length)
      //if (eth->tx.bytes_sent < eth->tx.packet_length)
 
      while (eth->tx.bytes_sent < eth->tx.packet_length)
        {
        {
          read_word =
          read_word =
            eval_direct32 (eth->tx.bytes_sent + eth->tx.bd_addr, 0, 0);
            eval_direct32 (eth->tx.bytes_sent + eth->tx.bd_addr, 0, 0);
          eth->tx_buff[eth->tx.bytes_sent] =
          eth->tx_buff[eth->tx.bytes_sent] =
            (unsigned char) (read_word >> 24);
            (unsigned char) (read_word >> 24);
Line 280... Line 281...
          eth->tx_buff[eth->tx.bytes_sent + 2] =
          eth->tx_buff[eth->tx.bytes_sent + 2] =
            (unsigned char) (read_word >> 8);
            (unsigned char) (read_word >> 8);
          eth->tx_buff[eth->tx.bytes_sent + 3] = (unsigned char) (read_word);
          eth->tx_buff[eth->tx.bytes_sent + 3] = (unsigned char) (read_word);
          eth->tx.bytes_sent += 4;
          eth->tx.bytes_sent += 4;
        }
        }
      else
      //else
        {
      //        {
          eth->tx.state = ETH_TXSTATE_TRANSMIT;
          eth->tx.state = ETH_TXSTATE_TRANSMIT;
        }
          //    }
      break;
      break;
    case ETH_TXSTATE_TRANSMIT:
    case ETH_TXSTATE_TRANSMIT:
      /* send packet */
      /* send packet */
      switch (eth->rtx_type)
      switch (eth->rtx_type)
        {
        {
        case ETH_RTX_FILE:
        case ETH_RTX_FILE:
          nwritten = write (eth->txfd, eth->tx_buff, eth->tx.packet_length);
          nwritten = write (eth->txfd, eth->tx_buff, eth->tx.packet_length);
          break;
          break;
        case ETH_RTX_TAP:
        case ETH_RTX_TAP:
          printf ("Writing TAP\n");
          /*
 
          printf ("Writing TAP\n");
 
 
 
          printf("packet %d bytes:",(int) eth->tx.packet_length );
 
          int j; for (j=0;j<eth->tx.packet_length;j++)
 
                   { if (j%16==0)printf("\n");
 
                     else if (j%8==0) printf(" ");
 
                     printf("%.2x ", eth->tx_buff[j]);
 
                   }
 
          printf("\nend packet:\n");
 
          */
          nwritten = write (eth->rtx_fd, eth->tx_buff, eth->tx.packet_length);
          nwritten = write (eth->rtx_fd, eth->tx_buff, eth->tx.packet_length);
          break;
          break;
        }
        }
 
 
      /* set BD status */
      /* set BD status */
Line 324... Line 335...
      if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
      if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
          TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M))
          TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M))
        {
        {
          if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, IRQ))
          if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, IRQ))
            {
            {
              printf ("ETH_TXSTATE_TRANSMIT interrupt\n");
              //printf ("ETH_TXSTATE_TRANSMIT interrupt\n");
              report_interrupt (eth->mac_int);
              report_interrupt (eth->mac_int);
            }
            }
        }
        }
 
 
      /* advance to next BD */
      /* advance to next BD */
Line 402... Line 413...
            {
            {
              eth->rx.fd = eth->rxfd;
              eth->rx.fd = eth->rxfd;
              eth->rx.offset = 0;
              eth->rx.offset = 0;
            }
            }
          eth->rx.state = ETH_RXSTATE_RECV;
          eth->rx.state = ETH_RXSTATE_RECV;
 
          //printf("rx_clk: going to ETH_RXSTATE_RECV\n");
        }
        }
      else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
      else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
        {
        {
          eth->rx.state = ETH_RXSTATE_IDLE;
          eth->rx.state = ETH_RXSTATE_IDLE;
        }
        }
Line 424... Line 436...
              fprintf (stderr, "Warning: Poll of WAIT4BD failed %s: ignored.\n",
              fprintf (stderr, "Warning: Poll of WAIT4BD failed %s: ignored.\n",
                       strerror (errno));
                       strerror (errno));
            }
            }
          else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
          else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
            {
            {
              printf ("Reading TAP\n");
              printf ("Reading TAP and all BDs full = BUSY\n");
              nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
              nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
 
 
              if (nread < 0)
              if (nread < 0)
                {
                {
                  fprintf (stderr,
                  fprintf (stderr,
Line 439... Line 451...
                {
                {
                  SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
                  SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
 
 
                  if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
                  if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
                    {
                    {
                      printf ("ETH_RXSTATE_WAIT4BD interrupt\n");
                      printf ("ETH_RXSTATE_WAIT4BD BUSY interrupt\n");
                      report_interrupt (eth->mac_int);
                      report_interrupt (eth->mac_int);
                    }
                    }
                }
                }
            }
            }
        }
        }
Line 507... Line 519...
                       "Warning: Poll of RXTATE_RECV failed %s: ignored.\n",
                       "Warning: Poll of RXTATE_RECV failed %s: ignored.\n",
                       strerror (errno));
                       strerror (errno));
            }
            }
          else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
          else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
            {
            {
              printf ("Reading TAP\n");
              //printf ("Reading TAP. ");
              nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
              nread = read (eth->rtx_fd, eth->rx_buff, ETH_MAXPL);
 
              //printf ("%d bytes read.\n",(int) nread);
              if (nread < 0)
              if (nread < 0)
                {
                {
                  fprintf (stderr,
                  fprintf (stderr,
                           "Warning: Read of RXTATE_RECV failed %s: ignored\n",
                           "Warning: Read of RXTATE_RECV failed %s: ignored\n",
                           strerror (errno));
                           strerror (errno));
                }
 
              else if (nread > 0)
 
                {
 
                  SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
 
 
 
                  if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
                  if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXE_M))
                    {
                    {
                      printf ("ETH_RXTATE_RECV interrupt\n");
                      SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXE);
 
                      printf ("ETH_RXTATE_RECV RXE interrupt\n");
                      report_interrupt (eth->mac_int);
                      report_interrupt (eth->mac_int);
                    }
                    }
                }
                }
 
 
            }
            }
 
 
          /* If not promiscouos mode, check the destination address */
          /* If not promiscouos mode, check the destination address */
          if (!TEST_FLAG (eth->regs.moder, ETH_MODER, PRO))
          if (!TEST_FLAG (eth->regs.moder, ETH_MODER, PRO) && nread)
            {
            {
              if (TEST_FLAG (eth->regs.moder, ETH_MODER, IAM)
              if (TEST_FLAG (eth->regs.moder, ETH_MODER, IAM)
                  && (eth->rx_buff[0] & 1))
                  && (eth->rx_buff[0] & 1))
                {
                {
                  /* Nothing for now */
                  /* Nothing for now */
                }
                }
 
 
              if (eth->mac_address[5] != eth->rx_buff[0] ||
 
                  eth->mac_address[4] != eth->rx_buff[1] ||
              if (((eth->mac_address[5] != eth->rx_buff[0]) &&
                  eth->mac_address[3] != eth->rx_buff[2] ||
                   (eth->rx_buff[5] != 0xff) ) ||
                  eth->mac_address[2] != eth->rx_buff[3] ||
                  ((eth->mac_address[4] != eth->rx_buff[1]) &&
                  eth->mac_address[1] != eth->rx_buff[4] ||
                   (eth->rx_buff[4] != 0xff) ) ||
                  eth->mac_address[0] != eth->rx_buff[5])
                  ((eth->mac_address[3] != eth->rx_buff[2]) &&
 
                   (eth->rx_buff[3] != 0xff) ) ||
 
                  ((eth->mac_address[2] != eth->rx_buff[3]) &&
 
                   (eth->rx_buff[2] != 0xff) ) ||
 
                  ((eth->mac_address[1] != eth->rx_buff[4]) &&
 
                   (eth->rx_buff[1] != 0xff) ) ||
 
                  ((eth->mac_address[0] != eth->rx_buff[5]) &&
 
                   (eth->rx_buff[0] != 0xff)))
 
 
 
              {
 
                /*
 
                  printf("ETH_RXSTATE dropping packet for %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
 
                       eth->rx_buff[0],
 
                       eth->rx_buff[1],
 
                       eth->rx_buff[2],
 
                       eth->rx_buff[3],
 
                       eth->rx_buff[4],
 
                       eth->rx_buff[5]);
 
                */
                break;
                break;
            }
            }
 
            }
 
 
          eth->rx.packet_length = nread;
          eth->rx.packet_length = nread;
          eth->rx.bytes_left = nread;
          eth->rx.bytes_left = nread;
          eth->rx.bytes_read = 0;
          eth->rx.bytes_read = 0;
 
 
 
          if (nread)
          eth->rx.state = ETH_RXSTATE_WRITEFIFO;
          eth->rx.state = ETH_RXSTATE_WRITEFIFO;
 
 
          break;
          break;
        case ETH_RTX_VAPI:
        case ETH_RTX_VAPI:
          break;
          break;
        }
        }
      break;
      break;
 
 
    case ETH_RXSTATE_WRITEFIFO:
    case ETH_RXSTATE_WRITEFIFO:
 
      //printf("ETH_RXSTATE_WRITEFIFO: writing to %d bytes 0x%.8x\n",(int)eth->rx.bytes_left, (unsigned int)eth->rx.bd_addr);
 
      if (eth->rx.bytes_left > 0){
 
        while((int) eth->rx.bytes_left){
      send_word = ((unsigned long) eth->rx_buff[eth->rx.bytes_read] << 24) |
      send_word = ((unsigned long) eth->rx_buff[eth->rx.bytes_read] << 24) |
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 1] << 16) |
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 1] << 16) |
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 2] << 8) |
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 2] << 8) |
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 3]);
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 3]);
      set_direct32 (eth->rx.bd_addr + eth->rx.bytes_read, send_word, 0, 0);
      set_direct32 (eth->rx.bd_addr + eth->rx.bytes_read, send_word, 0, 0);
      /* update counters */
      /* update counters */
 
          if (eth->rx.bytes_left >= 4)
 
            {
      eth->rx.bytes_left -= 4;
      eth->rx.bytes_left -= 4;
      eth->rx.bytes_read += 4;
      eth->rx.bytes_read += 4;
 
            }
 
          else
 
            {
 
              eth->rx.bytes_read += eth->rx.bytes_left;
 
              eth->rx.bytes_left = 0;
 
            }
 
        }
 
 
 
      }
 
      //printf("ETH_RXSTATE_WRITEFIFO: bytes read: 0x%.8x\n",(unsigned int)eth->rx.bytes_read);
      if (eth->rx.bytes_left <= 0)
      if (eth->rx.bytes_left <= 0)
        {
        {
          /* Write result to bd */
          /* Write result to bd */
          SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length);
          SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length+4);
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
 
          /*
          if (eth->rx.packet_length <
          if (eth->rx.packet_length <
              (GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL) - 4))
              (GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL) - 4))
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
          if (eth->rx.packet_length >
          if (eth->rx.packet_length >
              GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MAXFL))
              GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MAXFL))
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
 
          */
          eth->regs.bd_ram[eth->rx.bd_index] = eth->rx.bd;
          eth->regs.bd_ram[eth->rx.bd_index] = eth->rx.bd;
 
 
          /* advance to next BD */
          /* advance to next BD */
          if (TEST_FLAG (eth->rx.bd, ETH_RX_BD, WRAP)
          if (TEST_FLAG (eth->rx.bd, ETH_RX_BD, WRAP)
              || eth->rx.bd_index >= ETH_BD_COUNT)
              || eth->rx.bd_index >= ETH_BD_COUNT)
Line 594... Line 638...
            eth->rx.bd_index += 2;
            eth->rx.bd_index += 2;
 
 
          if ((TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M)) &&
          if ((TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M)) &&
              (TEST_FLAG (eth->rx.bd, ETH_RX_BD, IRQ)))
              (TEST_FLAG (eth->rx.bd, ETH_RX_BD, IRQ)))
            {
            {
              printf ("ETH_RXSTATE_WRITEFIFO interrupt\n");
              //printf ("ETH_RXSTATE_WRITEFIFO interrupt\n");
              report_interrupt (eth->mac_int);
              report_interrupt (eth->mac_int);
            }
            }
 
 
          /* ready to receive next packet */
          /* ready to receive next packet */
          eth->rx.state = ETH_RXSTATE_IDLE;
          eth->rx.state = ETH_RXSTATE_IDLE;
Line 743... Line 787...
 
 
      /* Turn it into a specific TAP device. If we haven't specified a
      /* Turn it into a specific TAP device. If we haven't specified a
         specific (persistent) device, one will be created, but that requires
         specific (persistent) device, one will be created, but that requires
         superuser, or at least CAP_NET_ADMIN capabilities. */
         superuser, or at least CAP_NET_ADMIN capabilities. */
      memset (&ifr, 0, sizeof(ifr));
      memset (&ifr, 0, sizeof(ifr));
      ifr.ifr_flags = IFF_TAP;
      ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
      strncpy (ifr.ifr_name, eth->tap_dev, IFNAMSIZ);
      strncpy (ifr.ifr_name, eth->tap_dev, IFNAMSIZ);
 
 
      if (ioctl (eth->rtx_fd, TUNSETIFF, (void *) &ifr) < 0)
      if (ioctl (eth->rtx_fd, TUNSETIFF, (void *) &ifr) < 0)
        {
        {
          fprintf (stderr, "Warning: Failed to set TAP device: %s\n",
          fprintf (stderr, "Warning: Failed to set TAP device: %s\n",
Line 777... Line 821...
 
 
  /* Clear TX/RX status and initialize buffer descriptor index. */
  /* Clear TX/RX status and initialize buffer descriptor index. */
  memset (&(eth->tx), 0, sizeof (eth->tx));
  memset (&(eth->tx), 0, sizeof (eth->tx));
  memset (&(eth->rx), 0, sizeof (eth->rx));
  memset (&(eth->rx), 0, sizeof (eth->rx));
 
 
 
  /* Reset TX/RX BD indexes */
 
  eth->tx.bd_index = 0;
  eth->rx.bd_index = eth->regs.tx_bd_num << 1;
  eth->rx.bd_index = eth->regs.tx_bd_num << 1;
 
 
  /* Initialize VAPI */
  /* Initialize VAPI */
  if (eth->base_vapi_id)
  if (eth->base_vapi_id)
    {
    {
Line 906... Line 952...
    {
    {
    case ETH_MODER:
    case ETH_MODER:
 
 
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
          TEST_FLAG (value, ETH_MODER, RXEN))
          TEST_FLAG (value, ETH_MODER, RXEN))
 
        {
 
          // Reset RX BD index
 
          eth->rx.bd_index = eth->regs.tx_bd_num << 1;
        SCHED_ADD (eth_controller_rx_clock, dat, 1);
        SCHED_ADD (eth_controller_rx_clock, dat, 1);
 
        }
      else if (!TEST_FLAG (value, ETH_MODER, RXEN))
      else if (!TEST_FLAG (value, ETH_MODER, RXEN))
        SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
        SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
 
 
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
          TEST_FLAG (value, ETH_MODER, TXEN))
          TEST_FLAG (value, ETH_MODER, TXEN))
 
        {
 
          eth->tx.bd_index = 0;
        SCHED_ADD (eth_controller_tx_clock, dat, 1);
        SCHED_ADD (eth_controller_tx_clock, dat, 1);
 
        }
      else if (!TEST_FLAG (value, ETH_MODER, TXEN))
      else if (!TEST_FLAG (value, ETH_MODER, TXEN))
        SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
        SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
 
 
      eth->regs.moder = value;
      eth->regs.moder = value;
 
 
      if (TEST_FLAG (value, ETH_MODER, RST))
      if (TEST_FLAG (value, ETH_MODER, RST))
        eth_reset (dat);
        eth_reset (dat);
      return;
      return;
    case ETH_INT_SOURCE:
    case ETH_INT_SOURCE:
      if (!(eth->regs.int_source & ~value) && eth->regs.int_source)
      // Clear interrupt if all interrupt sources have been dealt with
        clear_interrupt (eth->mac_int);
 
      eth->regs.int_source &= ~value;
      eth->regs.int_source &= ~value;
 
      if (!eth->regs.int_source)
 
        clear_interrupt (eth->mac_int);
 
 
      return;
      return;
    case ETH_INT_MASK:
    case ETH_INT_MASK:
      eth->regs.int_mask = value;
      eth->regs.int_mask = value;
 
      if (eth->regs.int_source & eth->regs.int_mask)
 
        report_interrupt (eth->mac_int);
 
      else
 
        clear_interrupt (eth->mac_int);
      return;
      return;
    case ETH_IPGT:
    case ETH_IPGT:
      eth->regs.ipgt = value;
      eth->regs.ipgt = value;
      return;
      return;
    case ETH_IPGR1:
    case ETH_IPGR1:
Line 1347... Line 1406...
              break;
              break;
            case MII_PHYSID2:
            case MII_PHYSID2:
              eth->regs.miirx_data = 0x1613; /* Micrel PHYID */
              eth->regs.miirx_data = 0x1613; /* Micrel PHYID */
              break;
              break;
            case MII_ADVERTISE:
            case MII_ADVERTISE:
              eth->regs.miirx_data = 0;
              eth->regs.miirx_data = ADVERTISE_FULL;
              break;
              break;
            case MII_LPA:
            case MII_LPA:
              eth->regs.miirx_data = LPA_DUPLEX | LPA_100;
              eth->regs.miirx_data = LPA_DUPLEX | LPA_100;
              break;
              break;
            case MII_EXPANSION:
            case MII_EXPANSION:
Line 1456... Line 1515...
  new->dma          = 0;
  new->dma          = 0;
  new->mac_int      = 0;
  new->mac_int      = 0;
  new->rtx_type     = ETH_RTX_FILE;
  new->rtx_type     = ETH_RTX_FILE;
  new->rx_channel   = 0;
  new->rx_channel   = 0;
  new->tx_channel   = 0;
  new->tx_channel   = 0;
 
  new->rtx_fd       = 0;
  new->rxfile       = strdup ("eth_rx");
  new->rxfile       = strdup ("eth_rx");
  new->txfile       = strdup ("eth_tx");
  new->txfile       = strdup ("eth_tx");
  new->tap_dev      = strdup ("");
  new->tap_dev      = strdup ("");
  new->base_vapi_id = 0;
  new->base_vapi_id = 0;
  new->phy_addr     = 0;
  new->phy_addr     = 0;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.