Beispiel #1
0
/*
 *  alloc a mbuf which can be used to describe the packet
 *  if work is error , return NULL
 *  then free wqe, reurn mbuf
 */
void *
oct_rx_process_work(cvmx_wqe_t *wq)
{
	void *pkt_virt;
	mbuf_t *m;

	if (wq->word2.s.rcv_error || cvmx_wqe_get_bufs(wq) > 1){
		/* 
		  *  Work has error, so drop
		  *  and now do not support jumbo packet
		  */
		printf("recv error\n");
		oct_packet_free(wq, wqe_pool);
		STAT_RECV_ERR;
		return NULL;
	}

	pkt_virt = (void *) cvmx_phys_to_ptr(wq->packet_ptr.s.addr);
	if(NULL == pkt_virt)
	{
		STAT_RECV_ADDR_ERR;
		return NULL;
	}
	
#ifdef SEC_RXTX_DEBUG
    printf("Received %u byte packet.\n", cvmx_wqe_get_len(wq));
    printf("Processing packet\n");
    cvmx_helper_dump_packet(wq);
#endif

	m = (mbuf_t *)MBUF_ALLOC();

	memset((void *)m, 0, sizeof(mbuf_t));

	m->magic_flag = MBUF_MAGIC_NUM;
	PKTBUF_SET_HW(m);
	
	m->packet_ptr.u64 = wq->packet_ptr.u64;

	m->input_port = cvmx_wqe_get_port(wq);
	
	m->pkt_totallen = cvmx_wqe_get_len(wq);
	m->pkt_ptr = pkt_virt;

	cvmx_fpa_free(wq, wqe_pool, 0);
	
	STAT_RECV_PC_ADD;
	STAT_RECV_PB_ADD(m->pkt_totallen);

	STAT_RECV_OK;
	return (void *)m;

}
void oct_tx_process_hw_work(cvmx_wqe_t *work, uint32_t outport)
{
	uint64_t queue = cvmx_pko_get_base_queue(outport);

	cvmx_pko_send_packet_prepare(outport, queue, CVMX_PKO_LOCK_CMD_QUEUE);

    /* Build a PKO pointer to this packet */
    cvmx_pko_command_word0_t pko_command;
    pko_command.u64 = 0;
    pko_command.s.segs = work->word2.s.bufs;
    pko_command.s.total_bytes = cvmx_wqe_get_len(work);

    /* Send the packet */
    cvmx_pko_return_value_t send_status = cvmx_pko_send_packet_finish(outport, queue, pko_command, work->packet_ptr, CVMX_PKO_LOCK_CMD_QUEUE);
    if (send_status != CVMX_PKO_SUCCESS)
    {
        printf("Failed to send packet using cvmx_pko_send_packet2\n");
        cvmx_helper_free_packet_data(work);
		STAT_TX_HW_SEND_ERR;
    }
	else
	{
		STAT_TX_SEND_OVER;
	}

    cvmx_fpa_free(work, wqe_pool, 0);
}