⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 405gp_enet.c

📁 嵌入式ARM的一些源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  emac_ip_addr = *srcaddr;
#endif

  if(first_init ==0)
    {
      /*
       * Connect interrupt service routines
       */
      irq_install_handler(9, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(10, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(11, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(12, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(13, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(14, (interrupt_handler_t *)enetInt, NULL);
      irq_install_handler(15, (interrupt_handler_t *)enetInt, NULL);
    }
  
  /* set up interrupt handler */
  /* setup interrupt controler to take interrupts from the MAL &
     EMAC */
  if(first_init ==0)
    mtdcr(uicer, mfdcr(uicer) | MAL_UIC_DEF | EMAC_UIC_DEF);

  /* set the MAL IER ??? names may change with new spec ??? */
  mal_ier = MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE |
    MAL_IER_PLBE;
  mtdcr(malier, mal_ier);

  /* Set EMAC IER */
  emac_ier = EMAC_ISR_PTLE |
    EMAC_ISR_BFCS | EMAC_ISR_PTLE |
    EMAC_ISR_ORE | EMAC_ISR_IRE;
  if(speed == _100BASET)
    emac_ier = emac_ier | EMAC_ISR_SYE;

  out32 (EMAC_IER, emac_ier);

  /*  if(first_init ==0)*/ /* test-only */
    set_msr(msr);            /* enable external */

  first_init =1;
  return (0);
}


/*-----------------------------------------------------------------------------+
+-----------------------------------------------------------------------------*/
int eth_send(volatile void *ptr, int len)
{
  struct enet_frame *ef_ptr;
  ulong time_start, time_now;
  unsigned long temp_txm0;


  ef_ptr = (struct enet_frame *) ptr;

  /*-----------------------------------------------------------------------+
    |  Copy in our address into the frame.
    +-----------------------------------------------------------------------*/
  (void) memcpy (ef_ptr->source_addr, emac_hwd_addr, ENET_ADDR_LENGTH);

  /*-----------------------------------------------------------------------+
    | If frame is too long or too short, modify length.
    +-----------------------------------------------------------------------*/
  if (len > ENET_MAX_MTU)
    len = ENET_MAX_MTU;

  //  memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len);
  memcpy ((void *) txbuf_ptr, (const void *) ptr, len);

  /*-----------------------------------------------------------------------+
    | set TX Buffer busy, and send it
    +-----------------------------------------------------------------------*/
  tx[tx_slot].ctrl = (MAL_TX_CTRL_LAST |
                      EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) &
    ~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA);
  if ((NUM_TX_BUFF - 1) == tx_slot)
    tx[tx_slot].ctrl |= MAL_TX_CTRL_WRAP;

  tx[tx_slot].data_len = (short) len;
  tx[tx_slot].ctrl |= MAL_TX_CTRL_READY;

  out32 (EMAC_TXM0, in32 (EMAC_TXM0) | EMAC_TXM0_GNP0);

  /*-----------------------------------------------------------------------+
    | poll unitl the packet is sent and then make sure it is OK
    +-----------------------------------------------------------------------*/
  time_start = get_timer (0);
  while (1)
    {
      temp_txm0 = in32(EMAC_TXM0);
      /* loop until either TINT turns on or 3 seconds elapse */
      if ((temp_txm0 & EMAC_TXM0_GNP0) != 0)
        {
          /* transmit is done, so now check for errors */
          /* there is an error, an inerrupt should hapen when we
             return                                    */
          time_now = get_timer (0);
          if ((time_now-time_start) > 3000)
            {
              return(-1);
            }
        } else
          return (0);

    } /* while */
}


/*-----------------------------------------------------------------------------+
| EnetInt.
| EnetInt is the interrupt handler.  It will determine the
| cause of the interrupt and call the apporpriate servive
| routine.
+-----------------------------------------------------------------------------*/
int
enetInt ()
{
  int serviced;
  int rc = -1;                  /* default to not us */
  unsigned long mal_isr;
  unsigned long emac_isr;
  unsigned long mal_rx_eob;
  unsigned long my_uicmsr;


  /* enter loop that stays in interrupt code until nothing to service */
  do
    {
      serviced = 0;

      my_uicmsr = mfdcr(uicmsr);
      if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0)
        {                           /* not for us */

          return (rc);
        }


      /* get and clear controller status interrupts */
      /* look at Mal and EMAC interrupts */
      if ((MAL_UIC_DEF & my_uicmsr) != 0)
        {                           /* we have a MAL interrupt */
          mal_isr = mfdcr(malesr);
          /* look for mal error */
          if ((my_uicmsr & MAL_UIC_ERR) !=0)
            {
              mal_err (mal_isr, my_uicmsr,MAL_UIC_DEF,MAL_UIC_ERR);
              serviced = 1;
              rc = 0;
            }
        }
      if ((EMAC_UIC_DEF & my_uicmsr) !=0)
        {                           /* look for EMAC errors */
          emac_isr = in32 (EMAC_ISR);
          if ((emac_ier & emac_isr)!=0)
            {
              emac_err (emac_isr);
              serviced = 1;
              rc = 0;
            }
        }
      if (((emac_ier & emac_isr)!=0) | ((MAL_UIC_ERR & my_uicmsr) != 0))
        {
          mtdcr(uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */
          return(rc);           /* we had errors so get out */
        }


      /* handle MAL RX EOB  interupt from a receive */
      /* check for EOB on valid channels            */
      if ((my_uicmsr & UIC_MAL_RXEOB) !=0)
        {
          mal_rx_eob = mfdcr(malrxeobisr);
          if ((mal_rx_eob & 0x80000000) !=0)
            {                         /* call emac routine for channel 0 */
              /* clear EOB
                 mtdcr(malrxeobisr, mal_rx_eob); */
              enet_rcv (emac_isr);
              /* indicate that we serviced an interrupt */
              serviced = 1;
              rc = 0;
            }
        }
      mtdcr(uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */
    }
  while (serviced);

  if (rc != 0)
    {
    }

  return (rc);
}

/*-----------------------------------------------------------------------------+
|  MAL Error Routine
+-----------------------------------------------------------------------------*/
void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,
              unsigned long mal_errr)
{
  mtdcr(malesr, isr); /* clear interrupt */
  printf ("MAL error occured.... ISR = %lx UIC = = %lx  MAL_DEF = %lx  MAL_ERR= %lx \n\r",
          isr, uic, maldef, mal_errr);

#if 0
  eth_init(NULL);
#endif

  mtdcr(malrxcarr, 0x80000000);
  mtdcr(malrxcarr, 0x00000000);
  mtdcr(malrxcasr, 0x80000000);

  mtdcr(maltxcarr, 0x80000000);     /* 2 channels */
  mtdcr(maltxcarr, 0x00000000);
  mtdcr(maltxcasr, 0x80000000);     /* 1 channel */
}

/*-----------------------------------------------------------------------------+
|  EMAC Error Routine
+-----------------------------------------------------------------------------*/
void emac_err (unsigned long isr)
{
  printf ("EMAC error occured.... ISR = %lx\n\r", isr);
  out32(EMAC_ISR, isr);
}

/*-----------------------------------------------------------------------------+
|  enet_rcv() handles the ethernet receive data
+-----------------------------------------------------------------------------*/
static void enet_rcv (unsigned long malisr)

{
  struct enet_frame *ef_ptr;
  unsigned long data_len;
  unsigned long rx_eob_isr;

  int handled=0;
  int i;

  rx_eob_isr = mfdcr(malrxeobisr);
  if ((0x80000000 >>( EMAC_RXCHL-1)) & rx_eob_isr)
    {
      /* clear EOB */
      mtdcr(malrxeobisr, rx_eob_isr);

      /* EMAC RX done */
      while (1)
        {                           /* do all */
          i = rx_slot;

          if (MAL_RX_CTRL_EMPTY & rx[i].ctrl)
            break;
          rx_slot++;
          if (NUM_RX_BUFF == rx_slot)
            rx_slot = 0;
          handled++;
          data_len = (unsigned long) rx[i].data_len;  /* Get len */
          if (data_len)
            {
              if (data_len > ENET_MAX_MTU)  /* Check len */
                data_len = 0;
              else
                {
                  if (EMAC_RX_ERRORS & rx[i].ctrl)
                    {                     /* Check Errors */
                      data_len = 0;
                      stats.rx_err_log[rx_err_index] = rx[i].ctrl;
                      rx_err_index++;
                      if (rx_err_index == MAX_ERR_LOG)
                        rx_err_index = 0;
                    }                     /* emac_erros         */
                }                       /* data_len < max mtu */
            }                         /* if data_len        */
          if (!data_len)
            {                         /* no data */
              rx[i].ctrl |= MAL_RX_CTRL_EMPTY;  /* Free Recv Buffer */

              stats.emac.data_len_err++;  /* Error at Rx */
            } /* !data_len */
          else
            {
              stats.emac.rx_frames++;
              stats.emac.rx += data_len;
              ef_ptr = (struct enet_frame *) rx[i].data_ptr;

              /*
               * Set rx pointer
               */
              rx_ptr = i;

              //              printf("X");  /* test-only */
              rx[i].ctrl |= MAL_RX_CTRL_EMPTY;  /* Free Recv Buffer */

            }                         /* if data_len */
        }                           /* while */
    }                             /* if EMACK_RXCHL */
}


int eth_rx(void)
{
  int length;
  int i;
  unsigned long msr;

  for (;;)
    {
      if (rx_ptr == -1)
        {
          length = -1;
          break;     /* nothing received - leave for() loop */
        }

      msr = get_msr();
      set_msr(msr & ~(MSR_EE));

      i = rx_ptr;
      length = rx[i].data_len;
      
      /* Pass the packet up to the protocol layers. */
      //      NetReceive(NetRxPackets[rxIdx], length - 4);
      //      NetReceive(NetRxPackets[i], length);
      NetReceive(NetRxPackets[i], length - 4);

      rx_ptr = -1;

      set_msr(msr);                 /* Enable IRQ's */
    }
  return length;
}

#endif /* CONFIG_PPC405GP */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -