コード例 #1
0
ファイル: e1000.c プロジェクト: 1015472/PX4NuttX
static int e1000_uiptxpoll(struct uip_driver_s *dev)
{
    struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
    int tail = e1000->tx_ring.tail;

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

    if (e1000->uip_dev.d_len > 0) {
		uip_arp_out(&e1000->uip_dev);
		e1000_transmit(e1000);

		/* Check if there is room in the device to hold another packet. If not,
		 * return a non-zero value to terminate the poll.
		 */
		if (!e1000->tx_ring.desc[tail].desc_status)
			return -1;
    }

    /* If zero is returned, the polling will continue until all connections have
     * been examined.
     */

    return 0;
}
コード例 #2
0
ファイル: syscall.c プロジェクト: stone-SJH/joslabs-byStone
/*stone's solution for lab6-A*/
static int
sys_transmit(uint8_t *data, uint32_t len){
	if ((uintptr_t) data >= UTOP)
		return -E_INVAL;
	else
  		return e1000_transmit(data, len);
}
コード例 #3
0
ファイル: syscall.c プロジェクト: ajsbu/cse506
// Try to send packet over network
static int
sys_net_try_send(char *data, int len)
{
        if ((uintptr_t)data >= UTOP) {
                return -E_INVAL;
        }

        return e1000_transmit(data, len);
}
コード例 #4
0
ファイル: e1000.c プロジェクト: bherrera/NuttX
static int e1000_txpoll(struct net_driver_s *dev)
{
    struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
    int tail = e1000->tx_ring.tail;

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

    if (e1000->netdev.d_len > 0)
    {
        /* Look up the destination MAC address and add it to the Ethernet
         * header.
         */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
        if (IFF_IS_IPv4(e1000->netdev.d_flags))
#endif
        {
            arp_out(&e1000->netdev);
        }
#endif /* CONFIG_NET_IPv4 */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
        else
#endif
        {
            neighbor_out(&e1000->netdev);
        }
#endif /* CONFIG_NET_IPv6 */

        /* Send the packet */

        e1000_transmit(e1000);

        /* Check if there is room in the device to hold another packet. If not,
         * return a non-zero value to terminate the poll.
         */

        if (!e1000->tx_ring.desc[tail].desc_status)
        {
            return -1;
        }
    }

    /* If zero is returned, the polling will continue until all connections have
     * been examined.
     */

    return 0;
}
コード例 #5
0
ファイル: syscall.c プロジェクト: bdmalab/6.828
//
// Transmit packet data pointed to by pkt to the e1000 network controller.
// If the e1000 has no more space in the transmission buffer, sys_e1000_transmit
// will yield the CPU and try later, much like the loop in ipc_send().
// If after 20 tries the packet cannot be transmitted, return -E_E1000_TXBUF_FULL.
//
// Returns 0 on succes, -E_BAD_ENV if the envid doesn't exist and -E_E1000_TXBUF_FULL
// if after 20 retries the packet still cannot be sent.
//
static int
sys_e1000_transmit(envid_t envid, char *pkt, size_t length)
{
	struct Env *env;

	if (envid2env(envid, &env, 0) != 0)
		return -E_BAD_ENV;

	user_mem_assert(env, pkt, length, PTE_W);

	int num_tries = 20;
	while((e1000_transmit(pkt, length) == -1) && (num_tries > 0)) {
		sys_yield();
		num_tries--;
	}

	if (num_tries == 0)
		return -E_E1000_TXBUF_FULL;

	return 0;
}
コード例 #6
0
ファイル: e1000.c プロジェクト: 1015472/PX4NuttX
static void e1000_receive(struct e1000_dev *e1000)
{
    int head = e1000->rx_ring.head;
    unsigned char *cp = (unsigned char *)
		(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
    int cnt;

    while (e1000->rx_ring.desc[head].desc_status) {

		/* Check for errors and update statistics */
	
		// Here we do not handle packets that exceed packet-buffer size
		if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) {
			cprintf("NIC READ: Oversized packet\n");
			goto next;
		}
	
		/* Check if the packet is a valid size for the uIP buffer configuration */
	
		// get the number of actual data-bytes in this packet
		cnt = e1000->rx_ring.desc[head].packet_length;
	
		if (cnt > CONFIG_NET_BUFSIZE || cnt < 14) {
			cprintf("NIC READ: invalid package size\n");
			goto next;
		}
    
		/* Copy the data data from the hardware to e1000->uip_dev.d_buf.  Set
		 * amount of data in e1000->uip_dev.d_len
		 */
    
		// now we try to copy these data-bytes to the UIP buffer
		memcpy(e1000->uip_dev.d_buf, cp, cnt);
		e1000->uip_dev.d_len = cnt;

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

#ifdef CONFIG_NET_IPv6
		if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
#else
			if (BUF->type == HTONS(UIP_ETHTYPE_IP))
#endif
			{
				uip_arp_ipin(&e1000->uip_dev);
				uip_input(&e1000->uip_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 (e1000->uip_dev.d_len > 0) {
					uip_arp_out(&e1000->uip_dev);
					e1000_transmit(e1000);
				}
			}
			else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
				uip_arp_arpin(&e1000->uip_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 (e1000->uip_dev.d_len > 0) {
					e1000_transmit(e1000);
				}
			}

    next:
		e1000->rx_ring.desc[head].desc_status = 0;
		e1000->rx_ring.head = (head + 1) % CONFIG_E1000_N_RX_DESC;
		e1000->rx_ring.free++;
		head = e1000->rx_ring.head;
		cp = (unsigned char *)(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
    }
}
コード例 #7
0
ファイル: e1000.c プロジェクト: bherrera/NuttX
static void e1000_receive(struct e1000_dev *e1000)
{
    int head = e1000->rx_ring.head;
    unsigned char *cp = (unsigned char *)
                        (e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
    int cnt;

    while (e1000->rx_ring.desc[head].desc_status)
    {
        /* Check for errors and update statistics */

        /* Here we do not handle packets that exceed packet-buffer size */

        if ((e1000->rx_ring.desc[head].desc_status & 3) == 1)
        {
            cprintf("NIC READ: Oversized packet\n");
            goto next;
        }

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

        /* get the number of actual data-bytes in this packet */

        cnt = e1000->rx_ring.desc[head].packet_length;

        if (cnt > CONFIG_NET_ETH_MTU || cnt < 14)
        {
            cprintf("NIC READ: invalid package size\n");
            goto next;
        }

        /* Copy the data data from the hardware to e1000->netdev.d_buf.  Set
         * amount of data in e1000->netdev.d_len
         */

        /* now we try to copy these data-bytes to the UIP buffer */

        memcpy(e1000->netdev.d_buf, cp, cnt);
        e1000->netdev.d_len = cnt;

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

        pkt_input(&e1000->netdev);
#endif

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

#ifdef CONFIG_NET_IPv4
        if (BUF->type == HTONS(ETHTYPE_IP))
        {
            nllvdbg("IPv4 frame\n");

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

            arp_ipin(&e1000->netdev);
            ipv4_input(&e1000->netdev);

            /* 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 (e1000->netdev.d_len > 0)
            {
                /* Update the Ethernet header with the correct MAC address */

#ifdef CONFIG_NET_IPv6
                if (IFF_IS_IPv4(e1000->netdev.d_flags))
#endif
                {
                    arp_out(&e1000->netdev);
                }
#ifdef CONFIG_NET_IPv6
                else
                {
                    neighbor_out(&e1000->netdev);
                }
#endif

                /* And send the packet */

                e1000_transmit(e1000);
            }
        }
        else
#endif
#ifdef CONFIG_NET_IPv6
            if (BUF->type == HTONS(ETHTYPE_IP6))
            {
                nllvdbg("Iv6 frame\n");

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

                ipv6_input(&e1000->netdev);

                /* 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 (e1000->netdev.d_len > 0)
                {
                    /* Update the Ethernet header with the correct MAC address */

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

                    /* And send the packet */

                    e1000_transmit(e1000);
                }
            }
            else
#endif
#ifdef CONFIG_NET_ARP
                if (BUF->type == htons(ETHTYPE_ARP))
                {
                    arp_arpin(&e1000->netdev);

                    /* 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 (e1000->netdev.d_len > 0)
                    {
                        e1000_transmit(e1000);
                    }
#endif
                }

next:
        e1000->rx_ring.desc[head].desc_status = 0;
        e1000->rx_ring.head = (head + 1) % CONFIG_E1000_N_RX_DESC;
        e1000->rx_ring.free++;
        head = e1000->rx_ring.head;
        cp = (unsigned char *)(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
    }
}