/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * version: DPDK.L.1.2.3-3
*/
#include <errno.h>
{
printf("usage: %s [--interactive|-i] [--help|-h] | ["
"--coremask=COREMASK --portmask=PORTMASK --numa "
+ "--mbuf-size= | --total-num-mbufs= | "
"--eth-peers-configfile= | "
"--eth-peer=X,M:M:M:M:M:M | --nb-cores= | --nb-ports= | "
"--pkt-filter-mode= |"
"--rss-ip | --rss-udp | "
"--rxpt= | --rxht= | --rxwt= | --rxfreet= | "
"--txpt= | --txht= | --txwt= | --txfreet= | "
- "--txrst= ]\n",
+ "--txrst= | --txqflags= ]\n",
progname);
printf(" --interactive: run in interactive mode\n");
printf(" --help: display this message and quit\n");
printf(" --nb-ports=N set the number of forwarding ports"
" (1 <= N <= %d)\n", nb_ports);
printf(" --coremask=COREMASK: hexadecimal bitmask of cores running "
- "the packet forwarding test\n");
+ "the packet forwarding test. The master lcore is reserved for "
+ "command line parsing only, and can not be masked on for running"
+ "the packet forwarding\n");
printf(" --portmask=PORTMASK: hexadecimal bitmask of ports used "
"by the packet forwarding test\n");
printf(" --numa: enable NUMA-aware allocation of RX/TX rings and of "
" RX memory buffers (mbufs)\n");
printf(" --mbuf-size=N set the data size of mbuf to N bytes\n");
+ printf(" --total-num-mbufs=N set the number of mbufs to be allocated "
+ "in mbuf pools\n");
printf(" --max-pkt-len=N set the maximum size of packet to N bytes\n");
printf(" --pkt-filter-mode=N: set Flow director mode "
"( N: none (default mode) or signature or perfect)\n");
printf(" --crc-strip: enable CRC stripping by hardware\n");
printf(" --enable-rx-cksum: enable rx hardware checksum offload\n");
printf(" --disable-hw-vlan: disable hardware vlan\n");
+ printf(" --enable-drop-en: enable per queue packet drop\n");
printf(" --disable-rss: disable rss\n");
printf(" --port-topology=N: set port topology (N: paired (default) or "
"chained)\n");
" (0 <= N <= value of txd)\n");
printf(" --txrst=N set the transmit RS bit threshold of TX rings to N"
" (0 <= N <= value of txd)\n");
+ printf(" --txqflags=0xXXXXXXXX hexidecimal bitmask of TX queue flags"
+ " (0 <= N <= 0x7FFFFFFF)\n");
+ printf(" --tx-queue-stats-mapping (port,queue,mapping)[,(port,queue,mapping]:"
+ " tx queues statistics counters mapping"
+ " (0 <= mapping <= %d)\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
+ printf(" --rx-queue-stats-mapping (port,queue,mapping)[,(port,queue,mapping]:"
+ " rx queues statistics counters mapping"
+ " (0 <= mapping <= %d)\n", RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
}
static int
cm = strtoull(coremask, &end, 16);
if ((coremask[0] == '\0') || (end == NULL) || (*end != '\0'))
rte_exit(EXIT_FAILURE, "Invalid fwd core mask\n");
- else
- set_fwd_lcores_mask((uint64_t) cm);
+ else if (set_fwd_lcores_mask((uint64_t) cm) < 0)
+ rte_exit(EXIT_FAILURE, "coremask is not valid\n");
}
/*
set_fwd_ports_mask((uint64_t) pm);
}
+
+static int
+parse_queue_stats_mapping_config(const char *q_arg, int is_rx)
+{
+ char s[256];
+ const char *p, *p0 = q_arg;
+ char *end;
+ enum fieldnames {
+ FLD_PORT = 0,
+ FLD_QUEUE,
+ FLD_STATS_COUNTER,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+ int i;
+ unsigned size;
+
+ /* reset from value set at definition */
+ is_rx ? (nb_rx_queue_stats_mappings = 0) : (nb_tx_queue_stats_mappings = 0);
+
+ while ((p = strchr(p0,'(')) != NULL) {
+ ++p;
+ if((p0 = strchr(p,')')) == NULL)
+ return -1;
+
+ size = p0 - p;
+ if(size >= sizeof(s))
+ return -1;
+
+ rte_snprintf(s, sizeof(s), "%.*s", size, p);
+ if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
+ return -1;
+ for (i = 0; i < _NUM_FLD; i++){
+ errno = 0;
+ int_fld[i] = strtoul(str_fld[i], &end, 0);
+ if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+ return -1;
+ }
+ /* Check mapping field is in correct range (0..RTE_ETHDEV_QUEUE_STAT_CNTRS-1) */
+ if (int_fld[FLD_STATS_COUNTER] >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+ printf("Stats counter not in the correct range 0..%d\n",
+ RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
+ return -1;
+ }
+
+ if (is_rx ? (nb_rx_queue_stats_mappings >= MAX_RX_QUEUE_STATS_MAPPINGS) :
+ (nb_tx_queue_stats_mappings >= MAX_TX_QUEUE_STATS_MAPPINGS)) {
+ printf("exceeded max number of %s queue statistics mappings: %hu\n",
+ is_rx ? "RX" : "TX",
+ is_rx ? nb_rx_queue_stats_mappings : nb_tx_queue_stats_mappings);
+ return -1;
+ }
+ if (!is_rx) {
+ tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].port_id =
+ (uint8_t)int_fld[FLD_PORT];
+ tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].queue_id =
+ (uint8_t)int_fld[FLD_QUEUE];
+ tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].stats_counter_id =
+ (uint8_t)int_fld[FLD_STATS_COUNTER];
+ ++nb_tx_queue_stats_mappings;
+ }
+ else {
+ rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].port_id =
+ (uint8_t)int_fld[FLD_PORT];
+ rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].queue_id =
+ (uint8_t)int_fld[FLD_QUEUE];
+ rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].stats_counter_id =
+ (uint8_t)int_fld[FLD_STATS_COUNTER];
+ ++nb_rx_queue_stats_mappings;
+ }
+
+ }
+/* Reassign the rx/tx_queue_stats_mappings pointer to point to this newly populated array rather */
+/* than to the default array (that was set at its definition) */
+ is_rx ? (rx_queue_stats_mappings = rx_queue_stats_mappings_array) :
+ (tx_queue_stats_mappings = tx_queue_stats_mappings_array);
+ return 0;
+}
+
+
void
launch_args_parse(int argc, char** argv)
{
int n, opt;
char **argvopt;
int opt_idx;
+ enum { TX, RX };
+
static struct option lgopts[] = {
{ "help", 0, 0, 0 },
{ "interactive", 0, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "numa", 0, 0, 0 },
{ "mbuf-size", 1, 0, 0 },
+ { "total-num-mbufs", 1, 0, 0 },
{ "max-pkt-len", 1, 0, 0 },
{ "pkt-filter-mode", 1, 0, 0 },
{ "pkt-filter-report-hash", 1, 0, 0 },
{ "pkt-filter-flexbytes-offset",1, 0, 0 },
{ "pkt-filter-drop-queue", 1, 0, 0 },
{ "crc-strip", 0, 0, 0 },
+ { "enable-rx-cksum", 0, 0, 0 },
{ "disable-hw-vlan", 0, 0, 0 },
+ { "enable-drop-en", 0, 0, 0 },
{ "disable-rss", 0, 0, 0 },
{ "port-topology", 1, 0, 0 },
{ "rss-ip", 0, 0, 0 },
{ "txwt", 1, 0, 0 },
{ "txfreet", 1, 0, 0 },
{ "txrst", 1, 0, 0 },
+ { "txqflags", 1, 0, 0 },
{ "rxpt", 1, 0, 0 },
{ "rxht", 1, 0, 0 },
{ "rxwt", 1, 0, 0 },
{ "rxfreet", 1, 0, 0 },
+ { "tx-queue-stats-mapping", 1, 0, 0 },
+ { "rx-queue-stats-mapping", 1, 0, 0 },
{ 0, 0, 0, 0 },
};
rte_exit(EXIT_FAILURE,
"mbuf-size should be > 0 and < 65536\n");
}
+ if (!strcmp(lgopts[opt_idx].name, "total-num-mbufs")) {
+ n = atoi(optarg);
+ if (n > 1024)
+ param_total_num_mbufs = (unsigned)n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "total-num-mbufs should be > 1024\n");
+ }
if (!strcmp(lgopts[opt_idx].name, "max-pkt-len")) {
n = atoi(optarg);
if (n >= ETHER_MIN_LEN) {
rx_mode.hw_strip_crc = 1;
if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum"))
rx_mode.hw_ip_checksum = 1;
- if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan"))
+
+ if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan")) {
rx_mode.hw_vlan_filter = 0;
+ rx_mode.hw_vlan_strip = 0;
+ rx_mode.hw_vlan_extend = 0;
+ }
+
+ if (!strcmp(lgopts[opt_idx].name, "enable-drop-en"))
+ rx_drop_en = 1;
+
if (!strcmp(lgopts[opt_idx].name, "disable-rss"))
rss_hf = 0;
if (!strcmp(lgopts[opt_idx].name, "port-topology")) {
if (!strcmp(lgopts[opt_idx].name, "rss-ip"))
rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6;
if (!strcmp(lgopts[opt_idx].name, "rss-udp"))
- rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6 |
- ETH_RSS_IPV4_UDP;
+ rss_hf = ETH_RSS_IPV4 |
+ ETH_RSS_IPV6 | ETH_RSS_IPV4_UDP;
if (!strcmp(lgopts[opt_idx].name, "rxq")) {
n = atoi(optarg);
if (n >= 1 && n <= (int) MAX_QUEUE_ID)
else
rte_exit(EXIT_FAILURE, "txrst must be >= 0\n");
}
+ if (!strcmp(lgopts[opt_idx].name, "txqflags")) {
+ char *end = NULL;
+ n = strtoul(optarg, &end, 16);
+ if (n >= 0)
+ txq_flags = (uint32_t)n;
+ else
+ rte_exit(EXIT_FAILURE,
+ "txqflags must be >= 0\n");
+ }
if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
n = atoi(optarg);
if (n >= 0)
else
rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n");
}
+ if (!strcmp(lgopts[opt_idx].name, "tx-queue-stats-mapping")) {
+ if (parse_queue_stats_mapping_config(optarg, TX)) {
+ rte_exit(EXIT_FAILURE,
+ "invalid TX queue statistics mapping config entered\n");
+ }
+ }
+ if (!strcmp(lgopts[opt_idx].name, "rx-queue-stats-mapping")) {
+ if (parse_queue_stats_mapping_config(optarg, RX)) {
+ rte_exit(EXIT_FAILURE,
+ "invalid RX queue statistics mapping config entered\n");
+ }
+ }
break;
case 'h':
usage(argv[0]);