@@ -46,6 +46,7 @@
typedef struct {
odp_pktio_t pktio;
+ odp_pktio_config_t config;
odp_pktout_queue_t pktout[MAX_WORKERS];
unsigned pktout_count;
} interface_t;
@@ -92,6 +93,7 @@ static struct {
*/
typedef struct {
odp_pktout_queue_t pktout; /**< Packet output queue to use*/
+ odp_pktout_config_opt_t *pktout_cfg; /**< Packet output offload config*/
odp_pool_t pool; /**< Pool for packet IO */
odp_timer_pool_t tp; /**< Timer pool handle */
odp_queue_t tq; /**< Queue for timeouts */
@@ -116,6 +118,9 @@ static args_t *args;
/** Barrier to sync threads execution */
static odp_barrier_t barrier;
+/** List of interfaces */
+static interface_t *ifs;
+
/* helper funcs */
static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
static void print_info(char *progname, appl_args_t *appl_args);
@@ -193,7 +198,8 @@ static int scan_ip(char *buf, unsigned int *paddr)
* @return Handle of created packet
* @retval ODP_PACKET_INVALID Packet could not be created
*/
-static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
+static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool,
+ odp_pktout_config_opt_t *pktout_cfg)
{
odp_packet_t pkt;
char *buf;
@@ -237,8 +243,10 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
udp->src_port = odp_cpu_to_be_16(args->appl.srcport);
udp->dst_port = odp_cpu_to_be_16(args->appl.dstport);
udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN);
- udp->chksum = 0;
- udp->chksum = odph_ipv4_udp_chksum(pkt);
+ if (!pktout_cfg->bit.udp_chksum) {
+ udp->chksum = 0;
+ udp->chksum = odph_ipv4_udp_chksum(pkt);
+ }
return pkt;
}
@@ -252,7 +260,8 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
* @return Handle of created packet
* @retval ODP_PACKET_INVALID Packet could not be created
*/
-static odp_packet_t pack_udp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
+static odp_packet_t pack_udp_pkt(odp_pool_t pool, odp_packet_t pkt_ref,
+ odp_pktout_config_opt_t *pktout_cfg)
{
odp_packet_t pkt;
char *buf;
@@ -274,7 +283,15 @@ static odp_packet_t pack_udp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF;
ip->id = odp_cpu_to_be_16(seq);
- ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ if (!pktout_cfg->bit.ipv4_chksum)
+ ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+
+ if (pktout_cfg->bit.ipv4_chksum || pktout_cfg->bit.udp_chksum) {
+ odp_packet_l2_offset_set(pkt, 0);
+ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
+ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
+ ODPH_IPV4HDR_LEN);
+ }
return pkt;
}
@@ -343,7 +360,8 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool)
* @return Handle of created packet
* @retval ODP_PACKET_INVALID Packet could not be created
*/
-static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
+static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref,
+ odp_pktout_config_opt_t *pktout_cfg)
{
odp_packet_t pkt;
char *buf;
@@ -368,7 +386,8 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff;
ip->id = odp_cpu_to_be_16(seq);
- ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ if (!pktout_cfg->bit.ipv4_chksum)
+ ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
/* icmp */
icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
@@ -382,6 +401,13 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
icmp->chksum = 0;
icmp->chksum = odph_chksum(icmp, args->appl.payload + ODPH_ICMPHDR_LEN);
+ if (pktout_cfg->bit.ipv4_chksum) {
+ odp_packet_l2_offset_set(pkt, 0);
+ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
+ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
+ ODPH_IPV4HDR_LEN);
+ }
+
return pkt;
}
@@ -422,6 +448,23 @@ static int create_pktio(const char *dev, odp_pool_t pool,
dev);
return -1;
}
+
+ odp_pktio_config_init(&itf->config);
+ itf->config.pktin.bit.ipv4_chksum = capa.config.pktin.bit.ipv4_chksum;
+ itf->config.pktin.bit.udp_chksum = capa.config.pktin.bit.udp_chksum;
+ itf->config.pktin.bit.drop_ipv4_err =
+ capa.config.pktin.bit.drop_ipv4_err;
+ itf->config.pktin.bit.drop_udp_err = capa.config.pktin.bit.drop_udp_err;
+
+ itf->config.pktout.bit.ipv4_chksum = capa.config.pktout.bit.ipv4_chksum;
+ itf->config.pktout.bit.udp_chksum = capa.config.pktout.bit.udp_chksum;
+
+ if (odp_pktio_config(itf->pktio, &itf->config)) {
+ EXAMPLE_ERR("Error: Failed to set interface configuration %s\n",
+ dev);
+ return -1;
+ }
+
if (num_rx_queues > capa.max_input_queues)
num_rx_queues = capa.max_input_queues;
@@ -482,6 +525,7 @@ static int gen_send_thread(void *arg)
int ret, i;
thread_args_t *thr_args;
odp_pktout_queue_t pktout;
+ odp_pktout_config_opt_t *pktout_cfg;
odp_packet_t pkt_array[MAX_UDP_TX_BURST];
int pkt_array_size;
int burst_start, burst_size;
@@ -491,9 +535,10 @@ static int gen_send_thread(void *arg)
thr_args = arg;
pktout = thr_args->pktout;
+ pktout_cfg = thr_args->pktout_cfg;
if (args->appl.mode == APPL_MODE_UDP) {
- pkt_ref = setup_udp_pkt_ref(thr_args->pool);
+ pkt_ref = setup_udp_pkt_ref(thr_args->pool, pktout_cfg);
pkt_array_size = args->appl.udp_tx_burst;
} else if (args->appl.mode == APPL_MODE_PING) {
pkt_ref = setup_icmp_pkt_ref(thr_args->pool);
@@ -522,7 +567,7 @@ static int gen_send_thread(void *arg)
if (args->appl.mode == APPL_MODE_UDP) {
for (i = 0; i < pkt_array_size; i++) {
pkt_array[i] = pack_udp_pkt(thr_args->pool,
- pkt_ref);
+ pkt_ref, pktout_cfg);
if (!odp_packet_is_valid(pkt_array[i]))
break;
}
@@ -533,7 +578,8 @@ static int gen_send_thread(void *arg)
break;
}
} else if (args->appl.mode == APPL_MODE_PING) {
- pkt_array[0] = pack_icmp_pkt(thr_args->pool, pkt_ref);
+ pkt_array[0] = pack_icmp_pkt(thr_args->pool, pkt_ref,
+ pktout_cfg);
if (!odp_packet_is_valid(pkt_array[0])) {
EXAMPLE_ERR(" [%2i] alloc_single failed\n",
thr);
@@ -684,6 +730,7 @@ static int gen_recv_thread(void *arg)
odp_packet_t pkts[MAX_RX_BURST], pkt;
odp_event_t events[MAX_RX_BURST];
int pkt_cnt, ev_cnt, i;
+ interface_t *itf;
thr = odp_thread_id();
(void)arg;
@@ -705,6 +752,30 @@ static int gen_recv_thread(void *arg)
continue;
for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) {
pkt = odp_packet_from_event(events[i]);
+ itf = &ifs[odp_pktio_index(odp_packet_input(pkt))];
+
+ if (odp_packet_has_ipv4(pkt)) {
+ if (itf->config.pktin.bit.ipv4_chksum) {
+ /* HW validation */
+ if (odp_packet_has_l3_error(pkt))
+ printf("HW detected L3 error\n");
+ } /* else SW validation */
+ }
+
+ if (odp_packet_has_udp(pkt)) {
+ if (itf->config.pktin.bit.udp_chksum) {
+ /* HW validation*/
+ if (odp_packet_has_l4_error(pkt))
+ printf("HW detected L4 error\n");
+ } /* else SW validation */
+ }
+ if (odp_packet_has_tcp(pkt)) {
+ if (itf->config.pktin.bit.tcp_chksum) {
+ /* HW validation */
+ if (odp_packet_has_l4_error(pkt))
+ printf("HW detected L4 error\n");
+ } /*else SW validation */
+ }
/* Drop packets with errors */
if (odp_unlikely(odp_packet_has_error(pkt))) {
@@ -714,9 +785,11 @@ static int gen_recv_thread(void *arg)
pkts[pkt_cnt++] = pkt;
}
- print_pkts(thr, pkts, pkt_cnt);
+ if (pkt_cnt) {
+ print_pkts(thr, pkts, pkt_cnt);
- odp_packet_free_multi(pkts, pkt_cnt);
+ odp_packet_free_multi(pkts, pkt_cnt);
+ }
}
return 0;
@@ -810,7 +883,6 @@ int main(int argc, char *argv[])
odp_pool_t tmop;
odp_queue_t tq;
odp_event_t ev;
- interface_t *ifs;
odp_instance_t instance;
odph_odpthread_params_t thr_params;
@@ -972,6 +1044,7 @@ int main(int argc, char *argv[])
abort();
}
(void)args->thread[1].pktout; /* Not used*/
+ (void)args->thread[1].pktout_cfg; /* Not used*/
args->thread[1].pool = pool;
args->thread[1].tp = tp;
args->thread[1].tq = tq;
@@ -1001,6 +1074,7 @@ int main(int argc, char *argv[])
abort();
}
args->thread[0].pktout = ifs[0].pktout[0];
+ args->thread[0].pktout_cfg = &ifs[0].config.pktout;
args->thread[0].pool = pool;
args->thread[0].tp = tp;
args->thread[0].tq = tq;
@@ -1032,15 +1106,18 @@ int main(int argc, char *argv[])
int (*thr_run_func)(void *);
int if_idx, pktout_idx;
- if (args->appl.mode == APPL_MODE_RCV)
+ if (args->appl.mode == APPL_MODE_RCV) {
(void)args->thread[i].pktout; /*not used*/
- else {
+ (void)args->thread[i].pktout_cfg; /*not used*/
+ } else {
if_idx = i % args->appl.if_count;
pktout_idx = (i / args->appl.if_count) %
ifs[if_idx].pktout_count;
args->thread[i].pktout =
ifs[if_idx].pktout[pktout_idx];
+ args->thread[i].pktout_cfg =
+ &ifs[if_idx].config.pktout;
}
tq = odp_queue_create("", NULL);
if (tq == ODP_QUEUE_INVALID) {
Signed-off-by: Bogdan Pricope <bogdan.pricope@linaro.org> --- example/generator/odp_generator.c | 107 ++++++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 15 deletions(-) -- 1.9.1