numam-dpdk/drivers/net/ark/ark_pktchkr.c
Ferruh Yigit ffc905f3b8 ethdev: separate driver APIs
Create a rte_ethdev_driver.h file and move PMD specific APIs here.
Drivers updated to include this new header file.

There is no update in header content and since ethdev.h included by
ethdev_driver.h, nothing changed from driver point of view, only
logically grouping of APIs. From applications point of view they can't
access to driver specific APIs anymore and they shouldn't.

More PMD specific data structures still remain in ethdev.h because of
inline functions in header use them. Those will be handled separately.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
2018-01-22 01:26:49 +01:00

479 lines
12 KiB
C

/*-
* BSD LICENSE
*
* Copyright (c) 2015-2017 Atomic Rules LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <getopt.h>
#include <sys/time.h>
#include <locale.h>
#include <unistd.h>
#include <rte_ethdev_driver.h>
#include <rte_malloc.h>
#include "ark_pktchkr.h"
#include "ark_logs.h"
static int set_arg(char *arg, char *val);
static int ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle);
#define ARK_MAX_STR_LEN 64
union OPTV {
int INT;
int BOOL;
uint64_t LONG;
char STR[ARK_MAX_STR_LEN];
};
enum OPTYPE {
OTINT,
OTLONG,
OTBOOL,
OTSTRING
};
struct OPTIONS {
char opt[ARK_MAX_STR_LEN];
enum OPTYPE t;
union OPTV v;
};
static struct OPTIONS toptions[] = {
{{"configure"}, OTBOOL, {1} },
{{"port"}, OTINT, {0} },
{{"mac-dump"}, OTBOOL, {0} },
{{"dg-mode"}, OTBOOL, {1} },
{{"run"}, OTBOOL, {0} },
{{"stop"}, OTBOOL, {0} },
{{"dump"}, OTBOOL, {0} },
{{"en_resync"}, OTBOOL, {0} },
{{"tuser_err_val"}, OTINT, {1} },
{{"gen_forever"}, OTBOOL, {0} },
{{"en_slaved_start"}, OTBOOL, {0} },
{{"vary_length"}, OTBOOL, {0} },
{{"incr_payload"}, OTINT, {0} },
{{"incr_first_byte"}, OTBOOL, {0} },
{{"ins_seq_num"}, OTBOOL, {0} },
{{"ins_time_stamp"}, OTBOOL, {1} },
{{"ins_udp_hdr"}, OTBOOL, {0} },
{{"num_pkts"}, OTLONG, .v.LONG = 10000000000000L},
{{"payload_byte"}, OTINT, {0x55} },
{{"pkt_spacing"}, OTINT, {60} },
{{"pkt_size_min"}, OTINT, {2005} },
{{"pkt_size_max"}, OTINT, {1514} },
{{"pkt_size_incr"}, OTINT, {1} },
{{"eth_type"}, OTINT, {0x0800} },
{{"src_mac_addr"}, OTLONG, .v.LONG = 0xdC3cF6425060L},
{{"dst_mac_addr"}, OTLONG, .v.LONG = 0x112233445566L},
{{"hdr_dW0"}, OTINT, {0x0016e319} },
{{"hdr_dW1"}, OTINT, {0x27150004} },
{{"hdr_dW2"}, OTINT, {0x76967bda} },
{{"hdr_dW3"}, OTINT, {0x08004500} },
{{"hdr_dW4"}, OTINT, {0x005276ed} },
{{"hdr_dW5"}, OTINT, {0x40004006} },
{{"hdr_dW6"}, OTINT, {0x56cfc0a8} },
{{"start_offset"}, OTINT, {0} },
{{"dst_ip"}, OTSTRING, .v.STR = "169.254.10.240"},
{{"dst_port"}, OTINT, {65536} },
{{"src_port"}, OTINT, {65536} },
};
ark_pkt_chkr_t
ark_pktchkr_init(void *addr, int ord, int l2_mode)
{
struct ark_pkt_chkr_inst *inst =
rte_malloc("ark_pkt_chkr_inst",
sizeof(struct ark_pkt_chkr_inst), 0);
if (inst == NULL) {
PMD_DRV_LOG(ERR, "Failed to malloc ark_pkt_chkr_inst.\n");
return inst;
}
inst->sregs = (struct ark_pkt_chkr_stat_regs *)addr;
inst->cregs =
(struct ark_pkt_chkr_ctl_regs *)(((uint8_t *)addr) + 0x100);
inst->ordinal = ord;
inst->l2_mode = l2_mode;
return inst;
}
void
ark_pktchkr_uninit(ark_pkt_chkr_t handle)
{
rte_free(handle);
}
void
ark_pktchkr_run(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->sregs->pkt_start_stop = 0;
inst->sregs->pkt_start_stop = 0x1;
}
int
ark_pktchkr_stopped(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
uint32_t r = inst->sregs->pkt_start_stop;
return (((r >> 16) & 1) == 1);
}
void
ark_pktchkr_stop(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
int wait_cycle = 10;
inst->sregs->pkt_start_stop = 0;
while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
usleep(1000);
wait_cycle--;
PMD_DEBUG_LOG(DEBUG, "Waiting for pktchk %d to stop...\n",
inst->ordinal);
}
PMD_DEBUG_LOG(DEBUG, "Pktchk %d stopped.\n", inst->ordinal);
}
int
ark_pktchkr_is_running(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
uint32_t r = inst->sregs->pkt_start_stop;
return ((r & 1) == 1);
}
static void
ark_pktchkr_set_pkt_ctrl(ark_pkt_chkr_t handle,
uint32_t gen_forever,
uint32_t vary_length,
uint32_t incr_payload,
uint32_t incr_first_byte,
uint32_t ins_seq_num,
uint32_t ins_udp_hdr,
uint32_t en_resync,
uint32_t tuser_err_val,
uint32_t ins_time_stamp)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
uint32_t r = (tuser_err_val << 16) | (en_resync << 0);
inst->sregs->pkt_ctrl = r;
if (!inst->l2_mode)
ins_udp_hdr = 0;
r = ((gen_forever << 24) |
(vary_length << 16) |
(incr_payload << 12) |
(incr_first_byte << 8) |
(ins_time_stamp << 5) |
(ins_seq_num << 4) |
ins_udp_hdr);
inst->cregs->pkt_ctrl = r;
}
static
int
ark_pktchkr_is_gen_forever(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
uint32_t r = inst->cregs->pkt_ctrl;
return (((r >> 24) & 1) == 1);
}
int
ark_pktchkr_wait_done(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
if (ark_pktchkr_is_gen_forever(handle)) {
PMD_DEBUG_LOG(ERR, "Pktchk wait_done will not terminate"
" because gen_forever=1\n");
return -1;
}
int wait_cycle = 10;
while (!ark_pktchkr_stopped(handle) && (wait_cycle > 0)) {
usleep(1000);
wait_cycle--;
PMD_DEBUG_LOG(DEBUG, "Waiting for packet checker %d's"
" internal pktgen to finish sending...\n",
inst->ordinal);
PMD_DEBUG_LOG(DEBUG, "Pktchk %d's pktgen done.\n",
inst->ordinal);
}
return 0;
}
int
ark_pktchkr_get_pkts_sent(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
return inst->cregs->pkts_sent;
}
void
ark_pktchkr_set_payload_byte(ark_pkt_chkr_t handle, uint32_t b)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->pkt_payload = b;
}
void
ark_pktchkr_set_pkt_size_min(ark_pkt_chkr_t handle, uint32_t x)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->pkt_size_min = x;
}
void
ark_pktchkr_set_pkt_size_max(ark_pkt_chkr_t handle, uint32_t x)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->pkt_size_max = x;
}
void
ark_pktchkr_set_pkt_size_incr(ark_pkt_chkr_t handle, uint32_t x)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->pkt_size_incr = x;
}
void
ark_pktchkr_set_num_pkts(ark_pkt_chkr_t handle, uint32_t x)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->num_pkts = x;
}
void
ark_pktchkr_set_src_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->src_mac_addr_h = (mac_addr >> 32) & 0xffff;
inst->cregs->src_mac_addr_l = mac_addr & 0xffffffff;
}
void
ark_pktchkr_set_dst_mac_addr(ark_pkt_chkr_t handle, uint64_t mac_addr)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->dst_mac_addr_h = (mac_addr >> 32) & 0xffff;
inst->cregs->dst_mac_addr_l = mac_addr & 0xffffffff;
}
void
ark_pktchkr_set_eth_type(ark_pkt_chkr_t handle, uint32_t x)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
inst->cregs->eth_type = x;
}
void
ark_pktchkr_set_hdr_dW(ark_pkt_chkr_t handle, uint32_t *hdr)
{
uint32_t i;
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
for (i = 0; i < 7; i++)
inst->cregs->hdr_dw[i] = hdr[i];
}
void
ark_pktchkr_dump_stats(ark_pkt_chkr_t handle)
{
struct ark_pkt_chkr_inst *inst = (struct ark_pkt_chkr_inst *)handle;
PMD_STATS_LOG(INFO, "pkts_rcvd = (%'u)\n",
inst->sregs->pkts_rcvd);
PMD_STATS_LOG(INFO, "bytes_rcvd = (%'" PRIU64 ")\n",
inst->sregs->bytes_rcvd);
PMD_STATS_LOG(INFO, "pkts_ok = (%'u)\n",
inst->sregs->pkts_ok);
PMD_STATS_LOG(INFO, "pkts_mismatch = (%'u)\n",
inst->sregs->pkts_mismatch);
PMD_STATS_LOG(INFO, "pkts_err = (%'u)\n",
inst->sregs->pkts_err);
PMD_STATS_LOG(INFO, "first_mismatch = (%'u)\n",
inst->sregs->first_mismatch);
PMD_STATS_LOG(INFO, "resync_events = (%'u)\n",
inst->sregs->resync_events);
PMD_STATS_LOG(INFO, "pkts_missing = (%'u)\n",
inst->sregs->pkts_missing);
PMD_STATS_LOG(INFO, "min_latency = (%'u)\n",
inst->sregs->min_latency);
PMD_STATS_LOG(INFO, "max_latency = (%'u)\n",
inst->sregs->max_latency);
}
static struct OPTIONS *
options(const char *id)
{
unsigned int i;
for (i = 0; i < sizeof(toptions) / sizeof(struct OPTIONS); i++) {
if (strcmp(id, toptions[i].opt) == 0)
return &toptions[i];
}
PMD_DRV_LOG(ERR,
"pktchkr: Could not find requested option!, option = %s\n",
id);
return NULL;
}
static int
set_arg(char *arg, char *val)
{
struct OPTIONS *o = options(arg);
if (o) {
switch (o->t) {
case OTINT:
case OTBOOL:
o->v.INT = atoi(val);
break;
case OTLONG:
o->v.INT = atoll(val);
break;
case OTSTRING:
snprintf(o->v.STR, ARK_MAX_STR_LEN, "%s", val);
break;
}
return 1;
}
return 0;
}
/******
* Arg format = "opt0=v,opt_n=v ..."
******/
void
ark_pktchkr_parse(char *args)
{
char *argv, *v;
const char toks[] = "=\n\t\v\f \r";
argv = strtok(args, toks);
v = strtok(NULL, toks);
while (argv && v) {
set_arg(argv, v);
argv = strtok(NULL, toks);
v = strtok(NULL, toks);
}
}
static int32_t parse_ipv4_string(char const *ip_address);
static int32_t
parse_ipv4_string(char const *ip_address)
{
unsigned int ip[4];
if (sscanf(ip_address, "%u.%u.%u.%u",
&ip[0], &ip[1], &ip[2], &ip[3]) != 4)
return 0;
return ip[3] + ip[2] * 0x100 + ip[1] * 0x10000ul + ip[0] * 0x1000000ul;
}
void
ark_pktchkr_setup(ark_pkt_chkr_t handle)
{
uint32_t hdr[7];
int32_t dst_ip = parse_ipv4_string(options("dst_ip")->v.STR);
if (!options("stop")->v.BOOL && options("configure")->v.BOOL) {
ark_pktchkr_set_payload_byte(handle,
options("payload_byte")->v.INT);
ark_pktchkr_set_src_mac_addr(handle,
options("src_mac_addr")->v.INT);
ark_pktchkr_set_dst_mac_addr(handle,
options("dst_mac_addr")->v.LONG);
ark_pktchkr_set_eth_type(handle,
options("eth_type")->v.INT);
if (options("dg-mode")->v.BOOL) {
hdr[0] = options("hdr_dW0")->v.INT;
hdr[1] = options("hdr_dW1")->v.INT;
hdr[2] = options("hdr_dW2")->v.INT;
hdr[3] = options("hdr_dW3")->v.INT;
hdr[4] = options("hdr_dW4")->v.INT;
hdr[5] = options("hdr_dW5")->v.INT;
hdr[6] = options("hdr_dW6")->v.INT;
} else {
hdr[0] = dst_ip;
hdr[1] = options("dst_port")->v.INT;
hdr[2] = options("src_port")->v.INT;
hdr[3] = 0;
hdr[4] = 0;
hdr[5] = 0;
hdr[6] = 0;
}
ark_pktchkr_set_hdr_dW(handle, hdr);
ark_pktchkr_set_num_pkts(handle,
options("num_pkts")->v.INT);
ark_pktchkr_set_pkt_size_min(handle,
options("pkt_size_min")->v.INT);
ark_pktchkr_set_pkt_size_max(handle,
options("pkt_size_max")->v.INT);
ark_pktchkr_set_pkt_size_incr(handle,
options("pkt_size_incr")->v.INT);
ark_pktchkr_set_pkt_ctrl(handle,
options("gen_forever")->v.BOOL,
options("vary_length")->v.BOOL,
options("incr_payload")->v.BOOL,
options("incr_first_byte")->v.BOOL,
options("ins_seq_num")->v.INT,
options("ins_udp_hdr")->v.BOOL,
options("en_resync")->v.BOOL,
options("tuser_err_val")->v.INT,
options("ins_time_stamp")->v.INT);
}
if (options("stop")->v.BOOL)
ark_pktchkr_stop(handle);
if (options("run")->v.BOOL) {
PMD_DEBUG_LOG(DEBUG, "Starting packet checker on port %d\n",
options("port")->v.INT);
ark_pktchkr_run(handle);
}
}