Exemple #1
0
static void misoc_net_interrupt_work(FAR void *arg)
{
  FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;

  /* Process pending Ethernet interrupts */

  net_lock();

  /* Check if we received an incoming packet, if so, call misoc_net_receive() */

  if (ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER)
    {
      misoc_net_receive(priv);
    }

  /* Check if a packet transmission just completed.  If so, call misoc_net_txdone.
   * This may disable further Tx interrupts if there are no pending
   * transmissions.
   */

  if (ethmac_sram_reader_ev_pending_read() & ETHMAC_EV_SRAM_READER)
    {
      misoc_net_txdone(priv);
      ethmac_sram_reader_ev_pending_write(1);
    }

  net_unlock();

  /* Re-enable Ethernet interrupts */

  up_enable_irq(ETHMAC_INTERRUPT);
}
Exemple #2
0
static struct pbuf *liteeth_low_level_input(struct netif *netif)
{
    unsigned int rxslot;
    unsigned int rxlen;
    char *rxbuffer;
    struct pbuf *p, *q;

    p = NULL;

    if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) {
        rxslot = ethmac_sram_writer_slot_read();
        rxlen = ethmac_sram_writer_length_read();
        /* dest MAC + source MAC + 802.1Q + ethertype + payload (MTU) */
        if(rxlen <= (netif->mtu + 18)) {
            if(rxslot)
                rxbuffer = rxbuffer1;
            else
                rxbuffer = rxbuffer0;

            p = pbuf_alloc(PBUF_RAW, rxlen, PBUF_POOL);
            q = p;
            while(q) {
                memcpy(q->payload, rxbuffer, q->len);
                rxbuffer += q->len;
                if(q->tot_len != q->len)
                    q = q->next;
                else
                    q = NULL;
            }
        }
        ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
    }
    return p;
}
Exemple #3
0
static void lwip_service(void)
{
    sys_check_timeouts();
    if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) {
        liteeth_input(&netif);
        ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
    }
}
Exemple #4
0
static void misoc_net_receive(FAR struct misoc_net_driver_s *priv)
{
  uint8_t rxslot;
  uint32_t rxlen;

  do
    {
      /* Check for errors and update statistics */

      /* Check if the packet is a valid size for the network buffer
       * configuration.
       */

      /* Find rx slot */

      rxslot = ethmac_sram_writer_slot_read();

      /* Get rx len */

      rxlen = ethmac_sram_writer_length_read();

      /* Copy the data data from the hardware to priv->misoc_net_dev.d_buf.  Set
       * amount of data in priv->misoc_net_dev.d_len
       *
       * NOTE: These memcpy's could be avoided by simply setting the d_buf
       * pointer to the rx*_buf containing the received data.  Some additional
       * buffer management logic would also be required.
       */

      misoc_flush_dcache();

      if (rxslot)
        {
          memcpy(priv->misoc_net_dev.d_buf, priv->rx1_buf, rxlen);
        }
      else
        {
          memcpy(priv->misoc_net_dev.d_buf, priv->rx0_buf, rxlen);
        }

      /* Clear event pending */

      ethmac_sram_writer_ev_pending_write(1);

      priv->misoc_net_dev.d_len = rxlen;

#ifdef CONFIG_NET_PKT
      /* When packet sockets are enabled, feed the frame into the packet tap */

       pkt_input(&priv->misoc_net_dev);
#endif

      /* We only accept IP packets of the configured type and ARP packets */

#ifdef CONFIG_NET_IPv4
      if (BUF->type == HTONS(ETHTYPE_IP))
        {
          ninfo("IPv4 frame\n");
          NETDEV_RXIPV4(&priv->misoc_net_dev);

          /* Handle ARP on input then give the IPv4 packet to the network
           * layer
           */

          arp_ipin(&priv->misoc_net_dev);
          ipv4_input(&priv->misoc_net_dev);

          /* If the above function invocation resulted in data that should be
           * sent out on the network, the field  d_len will set to a value > 0.
           */

          if (priv->misoc_net_dev.d_len > 0)
            {
              /* Update the Ethernet header with the correct MAC address */

#ifdef CONFIG_NET_IPv6
              if (IFF_IS_IPv4(priv->misoc_net_dev.d_flags))
#endif
                {
                  arp_out(&priv->misoc_net_dev);
                }
#ifdef CONFIG_NET_IPv6
              else
                {
                  neighbor_out(&kel->misoc_net_dev);
                }
#endif

              /* And send the packet */

              misoc_net_transmit(priv);
            }
        }
      else
#endif
#ifdef CONFIG_NET_IPv6
      if (BUF->type == HTONS(ETHTYPE_IP6))
        {
          ninfo("Iv6 frame\n");
          NETDEV_RXIPV6(&priv->misoc_net_dev);

          /* Give the IPv6 packet to the network layer */

          ipv6_input(&priv->misoc_net_dev);

          /* If the above function invocation resulted in data that should be
           * sent out on the network, the field  d_len will set to a value > 0.
           */

          if (priv->misoc_net_dev.d_len > 0)
            {
              /* Update the Ethernet header with the correct MAC address */

#ifdef CONFIG_NET_IPv4
              if (IFF_IS_IPv4(priv->misoc_net_dev.d_flags))
                {
                  arp_out(&priv->misoc_net_dev);
                }
              else
#endif
#ifdef CONFIG_NET_IPv6
                {
                  neighbor_out(&priv->misoc_net_dev);
                }
#endif

              /* And send the packet */

              misoc_net_transmit(priv);
            }
        }
      else
#endif
#ifdef CONFIG_NET_ARP
      if (BUF->type == htons(ETHTYPE_ARP))
        {
          arp_arpin(&priv->misoc_net_dev);
          NETDEV_RXARP(&priv->misoc_net_dev);

          /* If the above function invocation resulted in data that should be
           * sent out on the network, the field  d_len will set to a value > 0.
           */

          if (priv->misoc_net_dev.d_len > 0)
            {
              misoc_net_transmit(priv);
            }
        }
#endif
      else
        {
          NETDEV_RXDROPPED(&priv->misoc_net_dev);
        }
    }
  while (ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER);
}