예제 #1
0
void oct_tx_process_hw(mbuf_t *mbuf, uint32_t outport)
{
    uint64_t queue;

    /* Build a PKO pointer to this packet */
    cvmx_pko_return_value_t send_status;
    cvmx_pko_command_word0_t pko_command;

    queue = cvmx_pko_get_base_queue(outport);

    cvmx_pko_send_packet_prepare(outport, queue, CVMX_PKO_LOCK_CMD_QUEUE);

    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(outport, queue, pko_command, mbuf->packet_ptr, CVMX_PKO_LOCK_CMD_QUEUE);
    if (send_status != CVMX_PKO_SUCCESS)
    {
        STAT_TX_HW_SEND_ERR;
        PACKET_DESTROY_DATA(mbuf);
    }
    else
    {
        STAT_TX_SEND_OVER;
    }
    MBUF_FREE(mbuf);
}
예제 #2
0
파일: oct-rxtx.c 프로젝트: lanxbrad/sec-fw
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;
	
}