void oct_tx_done_check()
{
    int port;
    uint16_t consumer;
    uint16_t producer;
    oct_pko_pend_tx_done_t *pend_tx_done;
    oct_softx_stat_t *oct_stx_local = oct_stx[LOCAL_CPU_ID];

    for( port = 0; port < OCT_PHY_PORT_MAX; port++ )
    {
        if(oct_stx_local->tx_done[port].tx_entries)
        {
            consumer = oct_stx_local->tx_done[port].consumer;
            producer = oct_stx_local->tx_done[port].producer;

            while(consumer != producer)
            {
                pend_tx_done = &(oct_stx_local->tx_done[port].pend_tx_done[consumer]);
                if( 0xFF == pend_tx_done->mem_ref ) {
                    break;
                }

                /*Free the packet*/
                PACKET_DESTROY_ALL(pend_tx_done->mb);

                consumer = (consumer + 1) & (OCT_PKO_TX_DESC_NUM - 1);
                oct_stx_local->tx_done[port].tx_entries--;
                oct_tx_entries[LOCAL_CPU_ID]--;
            }
            oct_stx_local->tx_done[port].consumer = consumer;
        }
    }

    return;
}
void oct_tx_process_sw(mbuf_t *mbuf, uint8_t outport)
{
    uint64_t queue;
    cvmx_pko_return_value_t send_status;

    uint8_t *dont_free_cookie = NULL;

    queue = cvmx_pko_get_base_queue(outport);

    cvmx_pko_send_packet_prepare(outport, queue, CVMX_PKO_LOCK_CMD_QUEUE);

    tx_done_t *tx_done = &(oct_stx[LOCAL_CPU_ID]->tx_done[outport]);
    if(tx_done->tx_entries < (OCT_PKO_TX_DESC_NUM - 1))
    {
        dont_free_cookie = oct_pend_tx_done_add(tx_done, (void *)mbuf);
    }
    else
    {
        PACKET_DESTROY_ALL(mbuf);
        STAT_TX_SW_DESC_ERR;
        return;
    }
    /*command word0*/
    cvmx_pko_command_word0_t pko_command;
    pko_command.u64 = 0;

    pko_command.s.segs = 1;
    pko_command.s.total_bytes = mbuf->pkt_totallen;

    pko_command.s.rsp = 1;
    pko_command.s.dontfree = 1;

    /*command word1*/
    cvmx_buf_ptr_t packet;
    packet.u64 = 0;
    packet.s.size = mbuf->pkt_totallen;
    packet.s.addr = (uint64_t)mbuf->pkt_ptr;

    /*command word2*/
    cvmx_pko_command_word2_t tx_ptr_word;
    tx_ptr_word.u64 = 0;
    tx_ptr_word.s.ptr = (uint64_t)cvmx_ptr_to_phys(dont_free_cookie);

    /* Send the packet */
    send_status = cvmx_pko_send_packet_finish3(outport, queue, pko_command, packet, tx_ptr_word.u64, CVMX_PKO_LOCK_CMD_QUEUE);
    if(send_status != CVMX_PKO_SUCCESS)
    {
        if(dont_free_cookie)
        {
            oct_pend_tx_done_remove(tx_done);
        }

        PACKET_DESTROY_ALL(mbuf);
        STAT_TX_SW_SEND_ERR;
        return;
    }
    else
    {
        STAT_TX_SEND_OVER;
    }

}
Beispiel #3
0
void oct_tx_process_mbuf(mbuf_t *mbuf, uint8_t port)
{
	uint64_t queue;
	cvmx_pko_return_value_t send_status;
	
	if(port > OCT_PHY_PORT_MAX)
	{
		printf("Send port is invalid");
		PACKET_DESTROY_ALL(mbuf);
		STAT_TX_SEND_PORT_ERR;
		return;
	}

	queue = cvmx_pko_get_base_queue(port);

	cvmx_pko_send_packet_prepare(port, queue, CVMX_PKO_LOCK_CMD_QUEUE);


	if(PKTBUF_IS_HW(mbuf))
	{
		/* Build a PKO pointer to this packet */
		cvmx_pko_command_word0_t pko_command;
		pko_command.u64 = 0;
		pko_command.s.segs = 1;
		pko_command.s.total_bytes = mbuf->pkt_totallen;

		/* Send the packet */
		send_status = cvmx_pko_send_packet_finish(port, queue, pko_command, mbuf->packet_ptr, CVMX_PKO_LOCK_CMD_QUEUE);
		if (send_status != CVMX_PKO_SUCCESS)
	    {
	        printf("Failed to send packet using cvmx_pko_send_packet2\n");
			STAT_TX_HW_SEND_ERR;
	        PACKET_DESTROY_DATA(mbuf);
	    }

		MBUF_FREE(mbuf);
	}
	else if(PKTBUF_IS_SW(mbuf))
	{
		uint8_t *dont_free_cookie = NULL;
		tx_done_t *tx_done = &(oct_stx[local_cpu_id]->tx_done[port]);
		if(tx_done->tx_entries < (OCT_PKO_TX_DESC_NUM - 1))
		{
			dont_free_cookie = oct_pend_tx_done_add(tx_done, (void *)mbuf);			
		}
		else
		{
			PACKET_DESTROY_ALL(mbuf);
			STAT_TX_SW_DESC_ERR;
			return;
		}
		/*command word0*/
		cvmx_pko_command_word0_t pko_command;
		pko_command.u64 = 0;
		
		pko_command.s.segs = 1;
		pko_command.s.total_bytes = mbuf->pkt_totallen;

		pko_command.s.rsp = 1;
		pko_command.s.dontfree = 1;

		/*command word1*/
		cvmx_buf_ptr_t packet;
		packet.u64 = 0;
		packet.s.size = mbuf->pkt_totallen;
		packet.s.addr = (uint64_t)mbuf->pkt_ptr;

		/*command word2*/
		cvmx_pko_command_word2_t tx_ptr_word;
		tx_ptr_word.u64 = 0;
		tx_ptr_word.s.ptr = (uint64_t)cvmx_ptr_to_phys(dont_free_cookie);

		/* Send the packet */
		send_status = cvmx_pko_send_packet_finish3(port, queue, pko_command, packet, tx_ptr_word.u64, CVMX_PKO_LOCK_CMD_QUEUE);
		if(send_status != CVMX_PKO_SUCCESS)
		{
			if(dont_free_cookie)
			{
				oct_pend_tx_done_remove(tx_done);
			}

			printf("Failed to send packet using cvmx_pko_send_packet3\n");
			
	        PACKET_DESTROY_ALL(mbuf);
			STAT_TX_SW_SEND_ERR;
			return;
		}
	}
	else
	{
		printf("pkt space %d is wrong, please check it\n", PKTBUF_SPACE_GET(mbuf));
	}

	STAT_TX_SEND_OVER;
	
}