dpdk/drivers/net/ark/ark_pktchkr.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright (c) 2015-2018 Atomic Rules LLC
   3 */
   4
   5#include <unistd.h>
   6
   7#include <rte_string_fns.h>
   8#include <rte_malloc.h>
   9
  10#include "ark_pktchkr.h"
  11#include "ark_logs.h"
  12
  13static int set_arg(char *arg, char *val);
  14static int ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle);
  15
  16#define ARK_MAX_STR_LEN 64
  17union OPTV {
  18        int INT;
  19        int BOOL;
  20        uint64_t LONG;
  21        char STR[ARK_MAX_STR_LEN];
  22};
  23
  24enum OPTYPE {
  25        OTINT,
  26        OTLONG,
  27        OTBOOL,
  28        OTSTRING
  29};
  30
  31struct OPTIONS {
  32        char opt[ARK_MAX_STR_LEN];
  33        enum OPTYPE t;
  34        union OPTV v;
  35};
  36
  37static struct OPTIONS toptions[] = {
  38        {{"configure"}, OTBOOL, {1} },
  39        {{"port"}, OTINT, {0} },
  40        {{"mac-dump"}, OTBOOL, {0} },
  41        {{"dg-mode"}, OTBOOL, {1} },
  42        {{"run"}, OTBOOL, {0} },
  43        {{"stop"}, OTBOOL, {0} },
  44        {{"dump"}, OTBOOL, {0} },
  45        {{"en_resync"}, OTBOOL, {0} },
  46        {{"tuser_err_val"}, OTINT, {1} },
  47        {{"gen_forever"}, OTBOOL, {0} },
  48        {{"en_slaved_start"}, OTBOOL, {0} },
  49        {{"vary_length"}, OTBOOL, {0} },
  50        {{"incr_payload"}, OTINT, {0} },
  51        {{"incr_first_byte"}, OTBOOL, {0} },
  52        {{"ins_seq_num"}, OTBOOL, {0} },
  53        {{"ins_time_stamp"}, OTBOOL, {1} },
  54        {{"ins_udp_hdr"}, OTBOOL, {0} },
  55        {{"num_pkts"}, OTLONG, .v.LONG = 10000000000000L},
  56        {{"payload_byte"}, OTINT, {0x55} },
  57        {{"pkt_spacing"}, OTINT, {60} },
  58        {{"pkt_size_min"}, OTINT, {2005} },
  59        {{"pkt_size_max"}, OTINT, {1514} },
  60        {{"pkt_size_incr"}, OTINT, {1} },
  61        {{"eth_type"}, OTINT, {0x0800} },
  62        {{"src_mac_addr"}, OTLONG, .v.LONG = 0xdC3cF6425060L},
  63        {{"dst_mac_addr"}, OTLONG, .v.LONG = 0x112233445566L},
  64        {{"hdr_dW0"}, OTINT, {0x0016e319} },
  65        {{"hdr_dW1"}, OTINT, {0x27150004} },
  66        {{"hdr_dW2"}, OTINT, {0x76967bda} },
  67        {{"hdr_dW3"}, OTINT, {0x08004500} },
  68        {{"hdr_dW4"}, OTINT, {0x005276ed} },
  69        {{"hdr_dW5"}, OTINT, {0x40004006} },
  70        {{"hdr_dW6"}, OTINT, {0x56cfc0a8} },
  71        {{"start_offset"}, OTINT, {0} },
  72        {{"dst_ip"}, OTSTRING, .v.STR = "169.254.10.240"},
  73        {{"dst_port"}, OTINT, {65536} },
  74        {{"src_port"}, OTINT, {65536} },
  75};
  76
  77ark_pkt_chkr_t
  78ark_pktchkr_init(void *addr, int ord, int l2_mode)
  79{
  80        struct ark_pkt_chkr_inst *inst =
  81                rte_malloc("ark_pkt_chkr_inst",
  82                           sizeof(struct ark_pkt_chkr_inst), 0);
  83        if (inst == NULL) {
  84                ARK_PMD_LOG(ERR, "Failed to malloc ark_pkt_chkr_inst.\n");
  85                return inst;
  86        }
  87        inst->sregs = (struct ark_pkt_chkr_stat_regs *)addr;
  88        inst->cregs =
  89                (struct ark_pkt_chkr_ctl_regs *)(((uint8_t *)addr) + 0x100);
  90        inst->ordinal = ord;
  91        inst->l2_mode = l2_mode;
  92        return inst;
  93}
  94
  95void
  96ark_pktchkr_uninit(ark_pkt_chkr_t handle)
  97{
  98        rte_free(handle);
  99}
 100
 101void
 102ark_pktchkr_run(ark_pkt_chkr_t handle)
 103{
 104        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 105
 106        inst->sregs->pkt_start_stop = 0;
 107        inst->sregs->pkt_start_stop = 0x1;
 108}
 109
 110int
 111ark_pktchkr_stopped(ark_pkt_chkr_t handle)
 112{
 113        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 114        uint32_t r = inst->sregs->pkt_start_stop;
 115
 116        return (((r >> 16) & 1) == 1);
 117}
 118
 119void
 120ark_pktchkr_stop(ark_pkt_chkr_t handle)
 121{
 122        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 123        int wait_cycle = 10;
 124
 125        inst->sregs->pkt_start_stop = 0;
 126        while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
 127                usleep(1000);
 128                wait_cycle--;
 129                ARK_PMD_LOG(DEBUG, "Waiting for pktchk %d to stop...\n",
 130                              inst->ordinal);
 131        }
 132        ARK_PMD_LOG(DEBUG, "Pktchk %d stopped.\n", inst->ordinal);
 133}
 134
 135int
 136ark_pktchkr_is_running(ark_pkt_chkr_t handle)
 137{
 138        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 139        uint32_t r = inst->sregs->pkt_start_stop;
 140
 141        return ((r & 1) == 1);
 142}
 143
 144static void
 145ark_pktchkr_set_pkt_ctrl(ark_pkt_chkr_t handle,
 146                         uint32_t gen_forever,
 147                         uint32_t vary_length,
 148                         uint32_t incr_payload,
 149                         uint32_t incr_first_byte,
 150                         uint32_t ins_seq_num,
 151                         uint32_t ins_udp_hdr,
 152                         uint32_t en_resync,
 153                         uint32_t tuser_err_val,
 154                         uint32_t ins_time_stamp)
 155{
 156        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 157        uint32_t r = (tuser_err_val << 16) | (en_resync << 0);
 158
 159        inst->sregs->pkt_ctrl = r;
 160        if (!inst->l2_mode)
 161                ins_udp_hdr = 0;
 162        r = ((gen_forever << 24) |
 163             (vary_length << 16) |
 164             (incr_payload << 12) |
 165             (incr_first_byte << 8) |
 166             (ins_time_stamp << 5) |
 167             (ins_seq_num << 4) |
 168             ins_udp_hdr);
 169        inst->cregs->pkt_ctrl = r;
 170}
 171
 172static
 173int
 174ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle)
 175{
 176        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 177        uint32_t r = inst->cregs->pkt_ctrl;
 178
 179        return (((r >> 24) & 1) == 1);
 180}
 181
 182int
 183ark_pktchkr_wait_done(ark_pkt_chkr_t handle)
 184{
 185        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 186
 187        if (ark_pktchkr_is_gen_forever(handle)) {
 188                ARK_PMD_LOG(NOTICE, "Pktchk wait_done will not terminate"
 189                              " because gen_forever=1\n");
 190                return -1;
 191        }
 192        int wait_cycle = 10;
 193
 194        while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
 195                usleep(1000);
 196                wait_cycle--;
 197                ARK_PMD_LOG(DEBUG, "Waiting for packet checker %d's"
 198                              " internal pktgen to finish sending...\n",
 199                              inst->ordinal);
 200                ARK_PMD_LOG(DEBUG, "Pktchk %d's pktgen done.\n",
 201                              inst->ordinal);
 202        }
 203        return 0;
 204}
 205
 206int
 207ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle)
 208{
 209        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 210
 211        return inst->cregs->pkts_sent;
 212}
 213
 214void
 215ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b)
 216{
 217        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 218
 219        inst->cregs->pkt_payload = b;
 220}
 221
 222void
 223ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x)
 224{
 225        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 226
 227        inst->cregs->pkt_size_min = x;
 228}
 229
 230void
 231ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x)
 232{
 233        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 234
 235        inst->cregs->pkt_size_max = x;
 236}
 237
 238void
 239ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x)
 240{
 241        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 242
 243        inst->cregs->pkt_size_incr = x;
 244}
 245
 246void
 247ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x)
 248{
 249        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 250
 251        inst->cregs->num_pkts = x;
 252}
 253
 254void
 255ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
 256{
 257        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 258
 259        inst->cregs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;
 260        inst->cregs->src_mac_addr_l = mac_addr & 0xffffffff;
 261}
 262
 263void
 264ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
 265{
 266        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 267
 268        inst->cregs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;
 269        inst->cregs->dst_mac_addr_l = mac_addr & 0xffffffff;
 270}
 271
 272void
 273ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x)
 274{
 275        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 276
 277        inst->cregs->eth_type = x;
 278}
 279
 280void
 281ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr)
 282{
 283        uint32_t i;
 284        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 285
 286        for (i = 0; i < 7; i++)
 287                inst->cregs->hdr_dw[i] = hdr[i];
 288}
 289
 290void
 291ark_pktchkr_dump_stats(ark_pkt_chkr_t handle)
 292{
 293        struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
 294
 295        ARK_PMD_LOG(INFO, "pkts_rcvd      = (%'u)\n",
 296                      inst->sregs->pkts_rcvd);
 297        ARK_PMD_LOG(INFO, "bytes_rcvd     = (%'" PRIU64 ")\n",
 298                      inst->sregs->bytes_rcvd);
 299        ARK_PMD_LOG(INFO, "pkts_ok        = (%'u)\n",
 300                      inst->sregs->pkts_ok);
 301        ARK_PMD_LOG(INFO, "pkts_mismatch  = (%'u)\n",
 302                      inst->sregs->pkts_mismatch);
 303        ARK_PMD_LOG(INFO, "pkts_err       = (%'u)\n",
 304                      inst->sregs->pkts_err);
 305        ARK_PMD_LOG(INFO, "first_mismatch = (%'u)\n",
 306                      inst->sregs->first_mismatch);
 307        ARK_PMD_LOG(INFO, "resync_events  = (%'u)\n",
 308                      inst->sregs->resync_events);
 309        ARK_PMD_LOG(INFO, "pkts_missing   = (%'u)\n",
 310                      inst->sregs->pkts_missing);
 311        ARK_PMD_LOG(INFO, "min_latency    = (%'u)\n",
 312                      inst->sregs->min_latency);
 313        ARK_PMD_LOG(INFO, "max_latency    = (%'u)\n",
 314                      inst->sregs->max_latency);
 315}
 316
 317static struct OPTIONS *
 318options(const char *id)
 319{
 320        unsigned int i;
 321
 322        for (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {
 323                if (strcmp(id, toptions[i].opt) == 0)
 324                        return &toptions[i];
 325        }
 326        ARK_PMD_LOG(ERR,
 327                    "pktchkr: Could not find requested option!, option = %s\n",
 328                    id);
 329        return NULL;
 330}
 331
 332static int
 333set_arg(char *arg, char *val)
 334{
 335        struct OPTIONS *o = options(arg);
 336
 337        if (o) {
 338                switch (o->t) {
 339                case OTINT:
 340                case OTBOOL:
 341                        o->v.INT = atoi(val);
 342                        break;
 343                case OTLONG:
 344                        o->v.INT = atoll(val);
 345                        break;
 346                case OTSTRING:
 347                        strlcpy(o->v.STR, val, ARK_MAX_STR_LEN);
 348                        break;
 349                }
 350                return 1;
 351        }
 352        return 0;
 353}
 354
 355/******
 356 * Arg format = "opt0=v,opt_n=v ..."
 357 ******/
 358void
 359ark_pktchkr_parse(char *args)
 360{
 361        char *argv, *v;
 362        const char toks[] = "=\n\t\v\f \r";
 363        argv = strtok(args, toks);
 364        v = strtok(NULL, toks);
 365        while (argv && v) {
 366                set_arg(argv, v);
 367                argv = strtok(NULL, toks);
 368                v = strtok(NULL, toks);
 369        }
 370}
 371
 372static int32_t parse_ipv4_string(char const *ip_address);
 373static int32_t
 374parse_ipv4_string(char const *ip_address)
 375{
 376        unsigned int ip[4];
 377
 378        if (sscanf(ip_address, "%u.%u.%u.%u",
 379                   &ip[0], &ip[1], &ip[2], &ip[3]) != 4)
 380                return 0;
 381        return ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;
 382}
 383
 384void
 385ark_pktchkr_setup(ark_pkt_chkr_t handle)
 386{
 387        uint32_t hdr[7];
 388        int32_t dst_ip = parse_ipv4_string(options("dst_ip")->v.STR);
 389
 390        if (!options("stop")->v.BOOL && options("configure")->v.BOOL) {
 391                ark_pktchkr_set_payload_byte(handle,
 392                                             options("payload_byte")->v.INT);
 393                ark_pktchkr_set_src_mac_addr(handle,
 394                                             options("src_mac_addr")->v.INT);
 395                ark_pktchkr_set_dst_mac_addr(handle,
 396                                             options("dst_mac_addr")->v.LONG);
 397
 398                ark_pktchkr_set_eth_type(handle,
 399                                         options("eth_type")->v.INT);
 400                if (options("dg-mode")->v.BOOL) {
 401                        hdr[0] = options("hdr_dW0")->v.INT;
 402                        hdr[1] = options("hdr_dW1")->v.INT;
 403                        hdr[2] = options("hdr_dW2")->v.INT;
 404                        hdr[3] = options("hdr_dW3")->v.INT;
 405                        hdr[4] = options("hdr_dW4")->v.INT;
 406                        hdr[5] = options("hdr_dW5")->v.INT;
 407                        hdr[6] = options("hdr_dW6")->v.INT;
 408                } else {
 409                        hdr[0] = dst_ip;
 410                        hdr[1] = options("dst_port")->v.INT;
 411                        hdr[2] = options("src_port")->v.INT;
 412                        hdr[3] = 0;
 413                        hdr[4] = 0;
 414                        hdr[5] = 0;
 415                        hdr[6] = 0;
 416                }
 417                ark_pktchkr_set_hdr_dW(handle, hdr);
 418                ark_pktchkr_set_num_pkts(handle,
 419                                         options("num_pkts")->v.INT);
 420                ark_pktchkr_set_pkt_size_min(handle,
 421                                             options("pkt_size_min")->v.INT);
 422                ark_pktchkr_set_pkt_size_max(handle,
 423                                             options("pkt_size_max")->v.INT);
 424                ark_pktchkr_set_pkt_size_incr(handle,
 425                                              options("pkt_size_incr")->v.INT);
 426                ark_pktchkr_set_pkt_ctrl(handle,
 427                                         options("gen_forever")->v.BOOL,
 428                                         options("vary_length")->v.BOOL,
 429                                         options("incr_payload")->v.BOOL,
 430                                         options("incr_first_byte")->v.BOOL,
 431                                         options("ins_seq_num")->v.INT,
 432                                         options("ins_udp_hdr")->v.BOOL,
 433                                         options("en_resync")->v.BOOL,
 434                                         options("tuser_err_val")->v.INT,
 435                                         options("ins_time_stamp")->v.INT);
 436        }
 437
 438        if (options("stop")->v.BOOL)
 439                ark_pktchkr_stop(handle);
 440
 441        if (options("run")->v.BOOL) {
 442                ARK_PMD_LOG(DEBUG, "Starting packet checker on port %d\n",
 443                              options("port")->v.INT);
 444                ark_pktchkr_run(handle);
 445        }
 446}
 447