app/testpmd: handle SIGINT and SIGTERM
[dpdk.git] / app / test-pmd / testpmd.c
index 4c6aec6..1319917 100644 (file)
@@ -173,6 +173,9 @@ uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
 };
 uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
 
+enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
+/**< Split policy for packets to TX. */
+
 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
 
@@ -182,9 +185,6 @@ uint8_t dcb_config = 0;
 /* Whether the dcb is in testing status */
 uint8_t dcb_test = 0;
 
-/* DCB on and VT on mapping is default */
-enum dcb_queue_mapping_mode dcb_q_mapping = DCB_VT_Q_MAPPING;
-
 /*
  * Configurable number of RX/TX queues.
  */
@@ -754,9 +754,7 @@ fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
                        printf("  Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n",
                               port->rx_bad_ip_csum, port->rx_bad_l4_csum);
                if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
-                       printf("  RX-badcrc:  %-14"PRIu64" RX-badlen:  %-14"PRIu64
-                              "RX-error: %-"PRIu64"\n",
-                              stats->ibadcrc, stats->ibadlen, stats->ierrors);
+                       printf("  RX-error: %-"PRIu64"\n",  stats->ierrors);
                        printf("  RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
                }
 
@@ -775,9 +773,7 @@ fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
                        printf("  Bad-ipcsum:%14"PRIu64"    Bad-l4csum:%14"PRIu64"\n",
                               port->rx_bad_ip_csum, port->rx_bad_l4_csum);
                if (((stats->ierrors - stats->imissed) + stats->rx_nombuf) > 0) {
-                       printf("  RX-badcrc:              %14"PRIu64"    RX-badlen: %14"PRIu64
-                              "    RX-error:%"PRIu64"\n",
-                              stats->ibadcrc, stats->ibadlen, stats->ierrors);
+                       printf("  RX-error:%"PRIu64"\n", stats->ierrors);
                        printf("  RX-nombufs:             %14"PRIu64"\n",
                               stats->rx_nombuf);
                }
@@ -788,15 +784,6 @@ fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
                       (uint64_t) (stats->opackets + port->tx_dropped));
        }
 
-       /* Display statistics of XON/XOFF pause frames, if any. */
-       if ((stats->tx_pause_xon  | stats->rx_pause_xon |
-            stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) {
-               printf("  RX-XOFF:    %-14"PRIu64" RX-XON:     %-14"PRIu64"\n",
-                      stats->rx_pause_xoff, stats->rx_pause_xon);
-               printf("  TX-XOFF:    %-14"PRIu64" TX-XON:     %-14"PRIu64"\n",
-                      stats->tx_pause_xoff, stats->tx_pause_xon);
-       }
-
 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
        if (port->rx_stream)
                pkt_burst_stats_display("RX",
@@ -805,11 +792,6 @@ fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
                pkt_burst_stats_display("TX",
                        &port->tx_stream->tx_burst_stats);
 #endif
-       /* stats fdir */
-       if (fdir_conf.mode != RTE_FDIR_MODE_NONE)
-               printf("  Fdirmiss:%14"PRIu64"    Fdirmatch:%14"PRIu64"\n",
-                      stats->fdirmiss,
-                      stats->fdirmatch);
 
        if (port->rx_queue_stats_mapping_enabled) {
                printf("\n");
@@ -1153,10 +1135,6 @@ stop_packet_forwarding(void)
                port->stats.oerrors = 0;
                stats.rx_nombuf -= port->stats.rx_nombuf;
                port->stats.rx_nombuf = 0;
-               stats.fdirmatch -= port->stats.fdirmatch;
-               port->stats.rx_nombuf = 0;
-               stats.fdirmiss -= port->stats.fdirmiss;
-               port->stats.rx_nombuf = 0;
 
                total_recv += stats.ipackets;
                total_xmit += stats.opackets;
@@ -1534,7 +1512,7 @@ attach_port(char *identifier)
        nb_ports = rte_eth_dev_count();
 
        /* set_default_fwd_ports_config(); */
-       bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
+       memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids));
        i = 0;
        FOREACH_PORT(j, ports) {
                fwd_ports_ids[i] = j;
@@ -1569,7 +1547,7 @@ detach_port(uint8_t port_id)
        nb_ports = rte_eth_dev_count();
 
        /* set_default_fwd_ports_config(); */
-       bzero(fwd_ports_ids, sizeof(fwd_ports_ids));
+       memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids));
        i = 0;
        FOREACH_PORT(pi, ports) {
                fwd_ports_ids[i] = pi;
@@ -1592,13 +1570,16 @@ pmd_test_exit(void)
        if (test_done == 0)
                stop_packet_forwarding();
 
-       FOREACH_PORT(pt_id, ports) {
-               printf("Stopping port %d...", pt_id);
-               fflush(stdout);
-               rte_eth_dev_close(pt_id);
-               printf("done\n");
+       if (ports != NULL) {
+               no_link_check = 1;
+               FOREACH_PORT(pt_id, ports) {
+                       printf("\nShutting down port %d...\n", pt_id);
+                       fflush(stdout);
+                       stop_port(pt_id);
+                       close_port(pt_id);
+               }
        }
-       printf("bye...\n");
+       printf("\nBye...\n");
 }
 
 typedef void (*cmd_func_t)(void);
@@ -1852,115 +1833,131 @@ const uint16_t vlan_tags[] = {
 };
 
 static  int
-get_eth_dcb_conf(struct rte_eth_conf *eth_conf, struct dcb_config *dcb_conf)
+get_eth_dcb_conf(struct rte_eth_conf *eth_conf,
+                enum dcb_mode_enable dcb_mode,
+                enum rte_eth_nb_tcs num_tcs,
+                uint8_t pfc_en)
 {
-        uint8_t i;
+       uint8_t i;
 
        /*
         * Builds up the correct configuration for dcb+vt based on the vlan tags array
         * given above, and the number of traffic classes available for use.
         */
-       if (dcb_conf->dcb_mode == DCB_VT_ENABLED) {
-               struct rte_eth_vmdq_dcb_conf vmdq_rx_conf;
-               struct rte_eth_vmdq_dcb_tx_conf vmdq_tx_conf;
+       if (dcb_mode == DCB_VT_ENABLED) {
+               struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
+                               &eth_conf->rx_adv_conf.vmdq_dcb_conf;
+               struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
+                               &eth_conf->tx_adv_conf.vmdq_dcb_tx_conf;
 
                /* VMDQ+DCB RX and TX configrations */
-               vmdq_rx_conf.enable_default_pool = 0;
-               vmdq_rx_conf.default_pool = 0;
-               vmdq_rx_conf.nb_queue_pools =
-                       (dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
-               vmdq_tx_conf.nb_queue_pools =
-                       (dcb_conf->num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
-
-               vmdq_rx_conf.nb_pool_maps = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
-               for (i = 0; i < vmdq_rx_conf.nb_pool_maps; i++) {
-                       vmdq_rx_conf.pool_map[i].vlan_id = vlan_tags[ i ];
-                       vmdq_rx_conf.pool_map[i].pools = 1 << (i % vmdq_rx_conf.nb_queue_pools);
+               vmdq_rx_conf->enable_default_pool = 0;
+               vmdq_rx_conf->default_pool = 0;
+               vmdq_rx_conf->nb_queue_pools =
+                       (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
+               vmdq_tx_conf->nb_queue_pools =
+                       (num_tcs ==  ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
+
+               vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
+               for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
+                       vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
+                       vmdq_rx_conf->pool_map[i].pools =
+                               1 << (i % vmdq_rx_conf->nb_queue_pools);
                }
                for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
-                       vmdq_rx_conf.dcb_tc[i] = i;
-                       vmdq_tx_conf.dcb_tc[i] = i;
+                       vmdq_rx_conf->dcb_tc[i] = i;
+                       vmdq_tx_conf->dcb_tc[i] = i;
                }
 
-               /*set DCB mode of RX and TX of multiple queues*/
+               /* set DCB mode of RX and TX of multiple queues */
                eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
                eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
-               if (dcb_conf->pfc_en)
-                       eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
-               else
-                       eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
-
-               (void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_dcb_conf, &vmdq_rx_conf,
-                                sizeof(struct rte_eth_vmdq_dcb_conf)));
-               (void)(rte_memcpy(&eth_conf->tx_adv_conf.vmdq_dcb_tx_conf, &vmdq_tx_conf,
-                                sizeof(struct rte_eth_vmdq_dcb_tx_conf)));
-       }
-       else {
-               struct rte_eth_dcb_rx_conf rx_conf;
-               struct rte_eth_dcb_tx_conf tx_conf;
-
-               /* queue mapping configuration of DCB RX and TX */
-               if (dcb_conf->num_tcs == ETH_4_TCS)
-                       dcb_q_mapping = DCB_4_TCS_Q_MAPPING;
-               else
-                       dcb_q_mapping = DCB_8_TCS_Q_MAPPING;
-
-               rx_conf.nb_tcs = dcb_conf->num_tcs;
-               tx_conf.nb_tcs = dcb_conf->num_tcs;
-
-               for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++){
-                       rx_conf.dcb_tc[i] = i;
-                       tx_conf.dcb_tc[i] = i;
+       } else {
+               struct rte_eth_dcb_rx_conf *rx_conf =
+                               &eth_conf->rx_adv_conf.dcb_rx_conf;
+               struct rte_eth_dcb_tx_conf *tx_conf =
+                               &eth_conf->tx_adv_conf.dcb_tx_conf;
+
+               rx_conf->nb_tcs = num_tcs;
+               tx_conf->nb_tcs = num_tcs;
+
+               for (i = 0; i < num_tcs; i++) {
+                       rx_conf->dcb_tc[i] = i;
+                       tx_conf->dcb_tc[i] = i;
                }
-               eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB;
+               eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
+               eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf;
                eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
-               if (dcb_conf->pfc_en)
-                       eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT|ETH_DCB_PFC_SUPPORT;
-               else
-                       eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
-
-               (void)(rte_memcpy(&eth_conf->rx_adv_conf.dcb_rx_conf, &rx_conf,
-                                sizeof(struct rte_eth_dcb_rx_conf)));
-               (void)(rte_memcpy(&eth_conf->tx_adv_conf.dcb_tx_conf, &tx_conf,
-                                sizeof(struct rte_eth_dcb_tx_conf)));
        }
 
+       if (pfc_en)
+               eth_conf->dcb_capability_en =
+                               ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
+       else
+               eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
+
        return 0;
 }
 
 int
-init_port_dcb_config(portid_t pid,struct dcb_config *dcb_conf)
+init_port_dcb_config(portid_t pid,
+                    enum dcb_mode_enable dcb_mode,
+                    enum rte_eth_nb_tcs num_tcs,
+                    uint8_t pfc_en)
 {
        struct rte_eth_conf port_conf;
+       struct rte_eth_dev_info dev_info;
        struct rte_port *rte_port;
        int retval;
-       uint16_t nb_vlan;
        uint16_t i;
 
-       /* rxq and txq configuration in dcb mode */
-       nb_rxq = 128;
-       nb_txq = 128;
+       rte_eth_dev_info_get(pid, &dev_info);
+
+       /* If dev_info.vmdq_pool_base is greater than 0,
+        * the queue id of vmdq pools is started after pf queues.
+        */
+       if (dcb_mode == DCB_VT_ENABLED && dev_info.vmdq_pool_base > 0) {
+               printf("VMDQ_DCB multi-queue mode is nonsensical"
+                       " for port %d.", pid);
+               return -1;
+       }
+
+       /* Assume the ports in testpmd have the same dcb capability
+        * and has the same number of rxq and txq in dcb mode
+        */
+       if (dcb_mode == DCB_VT_ENABLED) {
+               nb_rxq = dev_info.max_rx_queues;
+               nb_txq = dev_info.max_tx_queues;
+       } else {
+               /*if vt is disabled, use all pf queues */
+               if (dev_info.vmdq_pool_base == 0) {
+                       nb_rxq = dev_info.max_rx_queues;
+                       nb_txq = dev_info.max_tx_queues;
+               } else {
+                       nb_rxq = (queueid_t)num_tcs;
+                       nb_txq = (queueid_t)num_tcs;
+
+               }
+       }
        rx_free_thresh = 64;
 
-       memset(&port_conf,0,sizeof(struct rte_eth_conf));
+       memset(&port_conf, 0, sizeof(struct rte_eth_conf));
        /* Enter DCB configuration status */
        dcb_config = 1;
 
-       nb_vlan = sizeof( vlan_tags )/sizeof( vlan_tags[ 0 ]);
        /*set configuration of DCB in vt mode and DCB in non-vt mode*/
-       retval = get_eth_dcb_conf(&port_conf, dcb_conf);
+       retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en);
        if (retval < 0)
                return retval;
 
        rte_port = &ports[pid];
-       memcpy(&rte_port->dev_conf, &port_conf,sizeof(struct rte_eth_conf));
+       memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
 
        rxtx_port_config(rte_port);
        /* VLAN filter */
        rte_port->dev_conf.rxmode.hw_vlan_filter = 1;
-       for (i = 0; i < nb_vlan; i++){
+       for (i = 0; i < RTE_DIM(vlan_tags); i++)
                rx_vft_set(pid, vlan_tags[i], 1);
-       }
 
        rte_eth_macaddr_get(pid, &rte_port->eth_addr);
        map_port_queue_stats_mapping_registers(pid, rte_port);
@@ -1990,12 +1987,35 @@ init_port(void)
                ports[pid].enabled = 1;
 }
 
+static void
+force_quit(void)
+{
+       pmd_test_exit();
+       prompt_exit();
+}
+
+static void
+signal_handler(int signum)
+{
+       if (signum == SIGINT || signum == SIGTERM) {
+               printf("\nSignal %d received, preparing to exit...\n",
+                               signum);
+               force_quit();
+               /* exit with the expected status */
+               signal(signum, SIG_DFL);
+               kill(getpid(), signum);
+       }
+}
+
 int
 main(int argc, char** argv)
 {
        int  diag;
        uint8_t port_id;
 
+       signal(SIGINT, signal_handler);
+       signal(SIGTERM, signal_handler);
+
        diag = rte_eal_init(argc, argv);
        if (diag < 0)
                rte_panic("Cannot init EAL\n");
@@ -2047,6 +2067,7 @@ main(int argc, char** argv)
                start_packet_forwarding(0);
                printf("Press enter to exit\n");
                rc = read(0, &c, 1);
+               pmd_test_exit();
                if (rc < 0)
                        return 1;
        }