1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2015-2018 Atomic Rules LLC
10 #include <rte_ethdev_driver.h>
11 #include <rte_malloc.h>
13 #include "ark_pktchkr.h"
16 static int set_arg(char *arg, char *val);
17 static int ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle);
19 #define ARK_MAX_STR_LEN 64
24 char STR[ARK_MAX_STR_LEN];
35 char opt[ARK_MAX_STR_LEN];
40 static struct OPTIONS toptions[] = {
41 {{"configure"}, OTBOOL, {1} },
42 {{"port"}, OTINT, {0} },
43 {{"mac-dump"}, OTBOOL, {0} },
44 {{"dg-mode"}, OTBOOL, {1} },
45 {{"run"}, OTBOOL, {0} },
46 {{"stop"}, OTBOOL, {0} },
47 {{"dump"}, OTBOOL, {0} },
48 {{"en_resync"}, OTBOOL, {0} },
49 {{"tuser_err_val"}, OTINT, {1} },
50 {{"gen_forever"}, OTBOOL, {0} },
51 {{"en_slaved_start"}, OTBOOL, {0} },
52 {{"vary_length"}, OTBOOL, {0} },
53 {{"incr_payload"}, OTINT, {0} },
54 {{"incr_first_byte"}, OTBOOL, {0} },
55 {{"ins_seq_num"}, OTBOOL, {0} },
56 {{"ins_time_stamp"}, OTBOOL, {1} },
57 {{"ins_udp_hdr"}, OTBOOL, {0} },
58 {{"num_pkts"}, OTLONG, .v.LONG = 10000000000000L},
59 {{"payload_byte"}, OTINT, {0x55} },
60 {{"pkt_spacing"}, OTINT, {60} },
61 {{"pkt_size_min"}, OTINT, {2005} },
62 {{"pkt_size_max"}, OTINT, {1514} },
63 {{"pkt_size_incr"}, OTINT, {1} },
64 {{"eth_type"}, OTINT, {0x0800} },
65 {{"src_mac_addr"}, OTLONG, .v.LONG = 0xdC3cF6425060L},
66 {{"dst_mac_addr"}, OTLONG, .v.LONG = 0x112233445566L},
67 {{"hdr_dW0"}, OTINT, {0x0016e319} },
68 {{"hdr_dW1"}, OTINT, {0x27150004} },
69 {{"hdr_dW2"}, OTINT, {0x76967bda} },
70 {{"hdr_dW3"}, OTINT, {0x08004500} },
71 {{"hdr_dW4"}, OTINT, {0x005276ed} },
72 {{"hdr_dW5"}, OTINT, {0x40004006} },
73 {{"hdr_dW6"}, OTINT, {0x56cfc0a8} },
74 {{"start_offset"}, OTINT, {0} },
75 {{"dst_ip"}, OTSTRING, .v.STR = "169.254.10.240"},
76 {{"dst_port"}, OTINT, {65536} },
77 {{"src_port"}, OTINT, {65536} },
81 ark_pktchkr_init(void *addr, int ord, int l2_mode)
83 struct ark_pkt_chkr_inst *inst =
84 rte_malloc("ark_pkt_chkr_inst",
85 sizeof(struct ark_pkt_chkr_inst), 0);
87 PMD_DRV_LOG(ERR, "Failed to malloc ark_pkt_chkr_inst.\n");
90 inst->sregs = (struct ark_pkt_chkr_stat_regs *)addr;
92 (struct ark_pkt_chkr_ctl_regs *)(((uint8_t *)addr) + 0x100);
94 inst->l2_mode = l2_mode;
99 ark_pktchkr_uninit(ark_pkt_chkr_t handle)
105 ark_pktchkr_run(ark_pkt_chkr_t handle)
107 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
109 inst->sregs->pkt_start_stop = 0;
110 inst->sregs->pkt_start_stop = 0x1;
114 ark_pktchkr_stopped(ark_pkt_chkr_t handle)
116 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
117 uint32_t r = inst->sregs->pkt_start_stop;
119 return (((r >> 16) & 1) == 1);
123 ark_pktchkr_stop(ark_pkt_chkr_t handle)
125 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
128 inst->sregs->pkt_start_stop = 0;
129 while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
132 PMD_DEBUG_LOG(DEBUG, "Waiting for pktchk %d to stop...\n",
135 PMD_DEBUG_LOG(DEBUG, "Pktchk %d stopped.\n", inst->ordinal);
139 ark_pktchkr_is_running(ark_pkt_chkr_t handle)
141 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
142 uint32_t r = inst->sregs->pkt_start_stop;
144 return ((r & 1) == 1);
148 ark_pktchkr_set_pkt_ctrl(ark_pkt_chkr_t handle,
149 uint32_t gen_forever,
150 uint32_t vary_length,
151 uint32_t incr_payload,
152 uint32_t incr_first_byte,
153 uint32_t ins_seq_num,
154 uint32_t ins_udp_hdr,
156 uint32_t tuser_err_val,
157 uint32_t ins_time_stamp)
159 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
160 uint32_t r = (tuser_err_val << 16) | (en_resync << 0);
162 inst->sregs->pkt_ctrl = r;
165 r = ((gen_forever << 24) |
166 (vary_length << 16) |
167 (incr_payload << 12) |
168 (incr_first_byte << 8) |
169 (ins_time_stamp << 5) |
172 inst->cregs->pkt_ctrl = r;
177 ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle)
179 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
180 uint32_t r = inst->cregs->pkt_ctrl;
182 return (((r >> 24) & 1) == 1);
186 ark_pktchkr_wait_done(ark_pkt_chkr_t handle)
188 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
190 if (ark_pktchkr_is_gen_forever(handle)) {
191 PMD_DEBUG_LOG(ERR, "Pktchk wait_done will not terminate"
192 " because gen_forever=1\n");
197 while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
200 PMD_DEBUG_LOG(DEBUG, "Waiting for packet checker %d's"
201 " internal pktgen to finish sending...\n",
203 PMD_DEBUG_LOG(DEBUG, "Pktchk %d's pktgen done.\n",
210 ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle)
212 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
214 return inst->cregs->pkts_sent;
218 ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b)
220 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
222 inst->cregs->pkt_payload = b;
226 ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x)
228 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
230 inst->cregs->pkt_size_min = x;
234 ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x)
236 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
238 inst->cregs->pkt_size_max = x;
242 ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x)
244 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
246 inst->cregs->pkt_size_incr = x;
250 ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x)
252 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
254 inst->cregs->num_pkts = x;
258 ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
260 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
262 inst->cregs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;
263 inst->cregs->src_mac_addr_l = mac_addr & 0xffffffff;
267 ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
269 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
271 inst->cregs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;
272 inst->cregs->dst_mac_addr_l = mac_addr & 0xffffffff;
276 ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x)
278 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
280 inst->cregs->eth_type = x;
284 ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr)
287 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
289 for (i = 0; i < 7; i++)
290 inst->cregs->hdr_dw[i] = hdr[i];
294 ark_pktchkr_dump_stats(ark_pkt_chkr_t handle)
296 struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
298 PMD_STATS_LOG(INFO, "pkts_rcvd = (%'u)\n",
299 inst->sregs->pkts_rcvd);
300 PMD_STATS_LOG(INFO, "bytes_rcvd = (%'" PRIU64 ")\n",
301 inst->sregs->bytes_rcvd);
302 PMD_STATS_LOG(INFO, "pkts_ok = (%'u)\n",
303 inst->sregs->pkts_ok);
304 PMD_STATS_LOG(INFO, "pkts_mismatch = (%'u)\n",
305 inst->sregs->pkts_mismatch);
306 PMD_STATS_LOG(INFO, "pkts_err = (%'u)\n",
307 inst->sregs->pkts_err);
308 PMD_STATS_LOG(INFO, "first_mismatch = (%'u)\n",
309 inst->sregs->first_mismatch);
310 PMD_STATS_LOG(INFO, "resync_events = (%'u)\n",
311 inst->sregs->resync_events);
312 PMD_STATS_LOG(INFO, "pkts_missing = (%'u)\n",
313 inst->sregs->pkts_missing);
314 PMD_STATS_LOG(INFO, "min_latency = (%'u)\n",
315 inst->sregs->min_latency);
316 PMD_STATS_LOG(INFO, "max_latency = (%'u)\n",
317 inst->sregs->max_latency);
320 static struct OPTIONS *
321 options(const char *id)
325 for (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {
326 if (strcmp(id, toptions[i].opt) == 0)
330 "pktchkr: Could not find requested option!, option = %s\n",
336 set_arg(char *arg, char *val)
338 struct OPTIONS *o = options(arg);
344 o->v.INT = atoi(val);
347 o->v.INT = atoll(val);
350 snprintf(o->v.STR, ARK_MAX_STR_LEN, "%s", val);
359 * Arg format = "opt0=v,opt_n=v ..."
362 ark_pktchkr_parse(char *args)
365 const char toks[] = "=\n\t\v\f \r";
366 argv = strtok(args, toks);
367 v = strtok(NULL, toks);
370 argv = strtok(NULL, toks);
371 v = strtok(NULL, toks);
375 static int32_t parse_ipv4_string(char const *ip_address);
377 parse_ipv4_string(char const *ip_address)
381 if (sscanf(ip_address, "%u.%u.%u.%u",
382 &ip[0], &ip[1], &ip[2], &ip[3]) != 4)
384 return ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;
388 ark_pktchkr_setup(ark_pkt_chkr_t handle)
391 int32_t dst_ip = parse_ipv4_string(options("dst_ip")->v.STR);
393 if (!options("stop")->v.BOOL && options("configure")->v.BOOL) {
394 ark_pktchkr_set_payload_byte(handle,
395 options("payload_byte")->v.INT);
396 ark_pktchkr_set_src_mac_addr(handle,
397 options("src_mac_addr")->v.INT);
398 ark_pktchkr_set_dst_mac_addr(handle,
399 options("dst_mac_addr")->v.LONG);
401 ark_pktchkr_set_eth_type(handle,
402 options("eth_type")->v.INT);
403 if (options("dg-mode")->v.BOOL) {
404 hdr[0] = options("hdr_dW0")->v.INT;
405 hdr[1] = options("hdr_dW1")->v.INT;
406 hdr[2] = options("hdr_dW2")->v.INT;
407 hdr[3] = options("hdr_dW3")->v.INT;
408 hdr[4] = options("hdr_dW4")->v.INT;
409 hdr[5] = options("hdr_dW5")->v.INT;
410 hdr[6] = options("hdr_dW6")->v.INT;
413 hdr[1] = options("dst_port")->v.INT;
414 hdr[2] = options("src_port")->v.INT;
420 ark_pktchkr_set_hdr_dW(handle, hdr);
421 ark_pktchkr_set_num_pkts(handle,
422 options("num_pkts")->v.INT);
423 ark_pktchkr_set_pkt_size_min(handle,
424 options("pkt_size_min")->v.INT);
425 ark_pktchkr_set_pkt_size_max(handle,
426 options("pkt_size_max")->v.INT);
427 ark_pktchkr_set_pkt_size_incr(handle,
428 options("pkt_size_incr")->v.INT);
429 ark_pktchkr_set_pkt_ctrl(handle,
430 options("gen_forever")->v.BOOL,
431 options("vary_length")->v.BOOL,
432 options("incr_payload")->v.BOOL,
433 options("incr_first_byte")->v.BOOL,
434 options("ins_seq_num")->v.INT,
435 options("ins_udp_hdr")->v.BOOL,
436 options("en_resync")->v.BOOL,
437 options("tuser_err_val")->v.INT,
438 options("ins_time_stamp")->v.INT);
441 if (options("stop")->v.BOOL)
442 ark_pktchkr_stop(handle);
444 if (options("run")->v.BOOL) {
445 PMD_DEBUG_LOG(DEBUG, "Starting packet checker on port %d\n",
446 options("port")->v.INT);
447 ark_pktchkr_run(handle);