示例#1
0
/*
 * Should do the actual transmission of the packet. The packet is
 * contained in the pbuf that is passed to the function. This buf
 * might be chained.
 */
bool_t
slip_output (slip_t *u, buf_t *p, small_uint_t prio)
{
    debug_printf ("slip_output: transmit %d bytes\n", p->tot_len);
    mutex_lock (&u->transmitter);

    if (u->out) {
        /* Занято, ставим в очередь. */
        if (buf_queue_is_full (&u->outq)) {
            ++u->netif.out_discards;
            mutex_unlock (&u->transmitter);
            debug_printf ("slip_output: overflow\n");
            buf_free (p);
            return 0;
        }
        buf_queue_put (&u->outq, p);
    } else {
        u->out = p;
        u->outseg = p;
        u->out_first = u->outseg->payload;
        u->out_limit = u->outseg->payload + u->outseg->len;
        u->out_flag = 1;
        slip_transmit_start (u);
    }
    mutex_unlock (&u->transmitter);
    return 1;
}
示例#2
0
/*
 * Receive interrupt task.
 */
static void
slip_receiver (void *arg)
{
    slip_t *u = arg;
    unsigned short len;

    /* Start receiver. */
    mutex_lock_irq (&u->netif.lock, RECEIVE_IRQ (u->port),
                    (handler_t) slip_receive_data, u);

    enable_receiver (u->port);
    enable_receive_interrupt (u->port);

    for (;;) {
        if (! u->in_ptr) {
            /* Allocate buffer for receive data. */
            u->in = buf_alloc (u->pool, u->netif.mtu, 16);
            if (u->in) {
                u->in_ptr = u->in->payload;
                u->in_limit = u->in_ptr + u->netif.mtu;
            } else {
                /* No buffer - ignore input. */
                debug_printf ("slip_receiver: out of memory\n");
                ++u->netif.in_discards;
            }
        }

        /* Wait for the receive interrupt. */
        mutex_wait (&u->netif.lock);

        /* Process all available received data. */
        if (u->in_ptr && u->in_ptr > u->in->payload) {
            len = u->in_ptr - u->in->payload;
            debug_printf ("slip_receiver(%ld): received %d bytes\n", u->netif.in_packets, len);
            buf_truncate (u->in, len);
            ++u->netif.in_packets;

            if (buf_queue_is_full (&u->inq)) {
                debug_printf ("slip_receiver: input overflow\n");
                ++u->netif.in_discards;

                /* Reuse the packet. */
                u->in_ptr = u->in->payload;
                u->in_limit = u->in_ptr + u->netif.mtu;
            } else {
                /* Enqueue the received packet. */
                buf_queue_put (&u->inq, u->in);
                u->in_ptr = 0;
            }
        }
#ifndef TRANSMIT_IRQ
        if (u->out_free)
            slip_out_next (u);
#endif
    }
}
示例#3
0
/*
 * Send the packet. Blocks the task until the packet is enqueued.
 */
bool_t
slip_send (slip_t *u, buf_t *p)
{
    mutex_lock (&u->transmitter);
    while (u->out && buf_queue_is_full (&u->outq))
        mutex_wait (&u->transmitter);

    if (u->out) {
        /* Занято, ставим в очередь. */
        buf_queue_put (&u->outq, p);
    } else {
        u->out = p;
        u->outseg = p;
        u->out_first = u->outseg->payload;
        u->out_limit = u->outseg->payload + u->outseg->len;
        u->out_flag = 1;
        slip_transmit_start (u);
    }
    mutex_unlock (&u->transmitter);
    return 1;
}
示例#4
0
/*
 * Do the actual transmission of the packet. The packet is contained
 * in the pbuf that is passed to the function. This pbuf might be chained.
 * Return 1 when the packet is succesfully queued for transmission.
 * Or return 0 if the packet is lost.
 */
static bool_t eth_output(eth_t *u, buf_t *p, small_uint_t prio) {
	mutex_lock(&u->netif.lock);
	/* debug_printf("From tcp out\n"); */
	/* Exit if link has failed */
	if (p->tot_len < 4 || p->tot_len > ETH_MTU /*||
	 ! (phy_read (u, PHY_STS) & PHY_STS_LINK)*/) {
		++u->netif.out_errors;
		mutex_unlock(&u->netif.lock);
		/*debug_printf ("output: transmit %d bytes, link failed\n", p->tot_len);*/
		netif_free_buf (&u->netif, p);
		return 0;
	}
	/*debug_printf ("output: transmit %d bytes\n", p->tot_len);*/

	if (ARM_ETH->STAT & ARM_ETH_X_EMPTY) {
		/* Смело отсылаем. */
		transmit_packet(u, p);
		mutex_unlock(&u->netif.lock);
		netif_free_buf (&u->netif, p);
		return 1;
	}

	/* Занято, ставим в очередь. */
	/*if (buf_queue_is_full(&u->outq)) {
	 // Нет места в очереди: теряем пакет.
	 ++u->netif.out_discards;
	 ++u->out_full_buf;
	 mutex_unlock(&u->netif.lock);
	 buf_free(p);
	 return 0;
	 }*/
	while (buf_queue_is_full(&u->outq))
		asm volatile ("nop;");
	buf_queue_put(&u->outq, p);
	mutex_unlock(&u->netif.lock);
	return 1;
}
示例#5
0
static void receive_packet(eth_t *u) {

#ifdef ETH_FIFO
	unsigned *dst = (unsigned *) u->rxbuf_physaddr;  // буфер для приёма
	uint32_t Rx_Stat, sizeBytes, sizeWords, i;
	Rx_Stat = ARM_ETH_RX_FIFO; /* Прочитать состояние приёмника */
	sizeBytes = ARM_ETH_PKT_LENGTH(Rx_Stat);
	if (sizeBytes - 4 > ETH_MTU) {
		++u->netif.in_errors;
		++u->in_discards_len_packet;
		ARM_ETH->STAT = 0;
		return;
	}
	sizeWords = (sizeBytes + 3) / 4;
	for (i = 0; i < sizeWords; i++) {
		*dst++ = ARM_ETH_RX_FIFO;
	}
	ARM_ETH->STAT = 0;
	if (Rx_Stat	& (ARM_ETH_PKT_SMB_ERR | ARM_ETH_PKT_CRC_ERR | ARM_ETH_PKT_DN_ERR | ARM_ETH_PKT_LF_ERR)) {
		++u->netif.in_errors;
		return;
	}

	++u->netif.in_packets;
	u->netif.in_bytes += sizeBytes;

	if (buf_queue_is_full(&u->inq)) {
		++u->netif.in_discards;
		++u->in_discards_full_buff;
		return;
	}

	buf_t *p = buf_alloc(u->pool, sizeBytes, 4); /* выделить фактически места */
	if (!p) {
		++u->netif.in_discards;
		++u->in_discards_full_buff;
		return;
	}
	memcpy(p->payload, u->rxbuf, sizeBytes);
	buf_queue_put(&u->inq, p);

#else

	uint16_t space_end = 0, tail, head;
	unsigned *src, *dst;
	uint32_t size, i, buf;
	uint16_t tmp[2], len;
	tail = ARM_ETH->R_TAIL;
	head = ARM_ETH->R_HEAD;

	if (tail > head) {
		space_end = tail - head;
	} else {
		space_end = ARM_ETH->DELIMITER - head;
	}

	src = (uint32_t*) (ARM_ETH_BUF_BASE + head);

	*((uint32_t*) tmp) = *src++;

	len = tmp[0];
	//debug_printf("Recive packet \tRx_stat = 0x%08x; \tbytes = %d\n",
	//		*((uint32_t*) tmp), tmp[0]);

	if ((len - 4) > ETH_MTU) {
		/*debug_printf("receive_data: len > MTU <%d>\n", len);*/
		++u->netif.in_discards;
		++u->in_discards_len_packet;
		ARM_ETH->R_HEAD = ARM_ETH->R_TAIL;
		ARM_ETH->STAT -= 0x20;
		return;
	}
	if ((tmp[1] << 16)
			& (ARM_ETH_PKT_SMB_ERR | ARM_ETH_PKT_CRC_ERR | ARM_ETH_PKT_DN_ERR
					/*| ARM_ETH_PKT_LEN_ERR | ARM_ETH_PKT_SF_ERR */
					| ARM_ETH_PKT_LF_ERR)) {
		debug_printf("Error  <0x%08X>\tsize = %d\n", tmp[1] << 16, tmp[0]);
		++u->netif.in_errors;
		ARM_ETH->R_HEAD = ARM_ETH->R_TAIL;
		ARM_ETH->STAT = 0;
		return;
	}
	u->netif.in_bytes += len;
	++u->netif.in_packets;
	space_end -= 4;

	if ((uint16_t) src > (ARM_ETH->DELIMITER - 1))
	src = (uint32_t*) ARM_ETH_BUF_BASE;

	if (buf_queue_is_full(&u->inq)) {
		/*debug_printf("receive_data: input overflow\n");*/
		++u->netif.in_discards;
		++u->in_discards_full_buff;
		ARM_ETH->R_HEAD = ARM_ETH->R_TAIL;
		ARM_ETH->STAT -= 0x20;
		return;
	}

	buf_t *p = buf_alloc(u->pool, len, 4); /* выделить фактически места */
	if (!p) {
		/* debug_printf("receive_data: ignore packet - out of memory\n"); */
		++u->netif.in_discards;
		++u->in_discards_full_buff;
		ARM_ETH->R_HEAD = ARM_ETH->R_TAIL;
		ARM_ETH->STAT -= 0x20;
		return;
	}
	dst = (unsigned *) &p->payload[0];

	//debug_printf("Rx frame, len = %d\tdst=0x%08X\n", len + 4, dst);
	size = (tmp[0] + 3) / 4;

	if (tmp[0] <= space_end) {
		for (i = 0; i < (size - 1); i++)
		*dst++ = *src++;

		buf = *src++;
	} else {
		size = size - space_end / 4;

		for (i = 0; i < (space_end / 4); i++)
		*dst++ = *src++;

		src = (uint32_t*) ARM_ETH_BUF_BASE;

		for (i = 0; i < (size - 1); i++)
		*dst++ = *src++;

		buf = *src++;
	}

	if ((uint16_t) src > (ARM_ETH->DELIMITER - 1))
	src = (uint32_t*) ARM_ETH_BUF_BASE;
	ARM_ETH->R_HEAD = (uint16_t) src;
	/* printf(&debug, "R_HEAD = <%04X> \tR_TAIL = <%04X>\n", ARM_ETH->R_HEAD, ARM_ETH->R_TAIL); */
	ARM_ETH->STAT = 0;
	buf_queue_put(&u->inq, p);
#endif //ETH_FIFO

}