Beispiel #1
0
/**
 * \brief Test GMAC read/write interfaces.
 *
 * \param test Current test case.
 */
static void run_gmac_read_write_test(const struct test_case *test)
{
	uint32_t ul_frm_size;
	uint8_t uc_rc = 0;
	uint32_t ul_retry_time = 0;

	/* Write the arp frame first */
	gmac_dev_write(&gs_gmac_dev, gs_arp_frame, sizeof(gs_arp_frame), NULL);

	while ( ul_retry_time < GMAC_UINT_TEST_MAX_RETRY_TIME ) {
		/* Read the frame in the gmac buffer */
		if (GMAC_OK != gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer,
						sizeof(gs_uc_eth_buffer), &ul_frm_size)) {
			continue;
		}

		/* Is arp frame sent? */
		if (strncmp((const char *)gs_uc_eth_buffer, (const char *)gs_uc_mac_address, sizeof(gs_uc_mac_address))) {
			uc_rc = 1;
			break;
		}

		ul_retry_time++;
	}

	test_assert_true(test, uc_rc == 1, "Test GMAC: gmac write error!");
}
Beispiel #2
0
BaseType_t xNetworkInterfaceOutput( xNetworkBufferDescriptor_t * const pxNetworkBuffer )
{
    BaseType_t xReturn = pdFAIL;
    int32_t x;

    /* Attempt to obtain access to a Tx descriptor. */
    for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
    {
        if( gmac_dev_write( &xGMACStruct, pxNetworkBuffer->pucEthernetBuffer, ( uint32_t ) pxNetworkBuffer->xDataLength, NULL ) == GMAC_OK )
        {
            /* The Tx has been initiated. */
            xReturn = pdPASS;
            break;
        }
        else
        {
            iptraceWAITING_FOR_TX_DMA_DESCRIPTOR();
            vTaskDelay( niTX_BUFFER_FREE_WAIT );
        }
    }

    /* Finished with the network buffer. */
    vNetworkBufferRelease( pxNetworkBuffer );

    return xReturn;
}
Beispiel #3
0
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
{
/* Do not wait too long for a free TX DMA buffer. */
const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );

	do {
		if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
		{
			/* Do not attempt to send packets as long as the Link Status is low. */
			break;
		}
		if( xTXDescriptorSemaphore == NULL )
		{
			/* Semaphore has not been created yet? */
			break;
		}
		if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
		{
			/* Time-out waiting for a free TX descriptor. */
			tx_release_count[ 3 ]++;
			break;
		}
		#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
		{
			/* Confirm that the pxDescriptor may be kept by the driver. */
			configASSERT( bReleaseAfterSend != pdFALSE );
		}
		#endif /* ipconfigZERO_COPY_TX_DRIVER */

		gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );

		#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
		{
			/* Confirm that the pxDescriptor may be kept by the driver. */
			bReleaseAfterSend = pdFALSE;
		}
		#endif /* ipconfigZERO_COPY_TX_DRIVER */
		/* Not interested in a call-back after TX. */
		iptraceNETWORK_INTERFACE_TRANSMIT();
	} while( 0 );

	if( bReleaseAfterSend != pdFALSE )
	{
		vReleaseNetworkBufferAndDescriptor( pxDescriptor );
	}
	return pdTRUE;
}
Beispiel #4
0
/**
 * \brief This function should 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.
 * note: Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
 *       strange results. You might consider waiting for space in the DMA queue
 *       to become available since the stack doesn't retry to send a packet
 *       dropped because of memory failure (except for the TCP timers).
 *
 * \param netif the lwip network interface structure for this ethernetif
 * \param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
 *
 * \return ERR_OK if the packet could be sent
 *         an err_t value if the packet couldn't be sent.
 */
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
    struct pbuf *q = NULL;
    int8_t pc_buf[NET_RW_BUFF_SIZE];
    int8_t *bufptr = &pc_buf[0];
    uint8_t uc_rc;

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE);    /* Drop the padding word */
#endif

    /* Check the buffer boundary */
    if (p->tot_len > NET_RW_BUFF_SIZE) {
        return ERR_BUF;
    }

    /* Clear the output buffer */
    memset(bufptr, 0x0, NET_RW_BUFF_SIZE);

    for (q = p; q != NULL; q = q->next) {
        /* Send the data from the pbuf to the interface, one pbuf at a
         * time. The size of the data in each pbuf is kept in the ->len
         * variable. */

        /* Send data from(q->payload, q->len); */
        memcpy(bufptr, q->payload, q->len);
        bufptr += q->len;
    }

    /* Signal that packet should be sent(); */
    uc_rc = gmac_dev_write(&gs_gmac_dev, pc_buf, p->tot_len, NULL);
    if (uc_rc != GMAC_OK) {
        return ERR_BUF;
    }

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE);    /* Reclaim the padding word */
#endif

    LINK_STATS_INC(link.xmit);

    return ERR_OK;
}