/* * 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); }