When a NIC is reset, a message will show it.
And then user can run the command "reset_port port_id"
to reset the port and to keep same port id without any
without any configuration.
This patch adds a testpmd command "reconfig_port port_id"
to test whether the port can be reconfigured to have
success Rx and Tx function.
The new command will configure the port with the simplest
setting which includes only 1 Rx queue, only 1 Tx queue,
Rx mode = None and Tx mode = None.
It check if the port can receive and forward some packets.
For example 100 packets in this new command.
Before testing with "reset_port port_id" and then
"reconfig_port port_id", current forwarding should be stopped
first to avoid crash.

Signed-off-by: Wei Dai <wei....@intel.com>
---
 app/test-pmd/cmdline.c | 31 ++++++++++++++++
 app/test-pmd/config.c  | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  1 +
 3 files changed, 130 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 90f6bde..1038cee 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2618,6 +2618,36 @@ cmdline_parse_inst_t cmd_reset_port = {
        },
 };
 
+/* *** reconfig a port with simplest settings only for test *** */
+struct cmd_reconfig_port_result {
+       cmdline_fixed_string_t command;
+       uint8_t port_id;
+};
+
+static void cmd_reconfig_port_parsed(__attribute__((unused)) void 
*parsed_result,
+                           __attribute__((unused)) struct cmdline *cl,
+                           __attribute__((unused)) void *data)
+{
+       struct cmd_reconfig_port_result *res = parsed_result;
+       reconfig_port(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_reconfig_port_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_reconfig_port_result, command, 
"reconfig_port");
+cmdline_parse_token_num_t cmd_reconfig_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_reconfig_port_result, port_id, UINT8);
+
+cmdline_parse_inst_t cmd_reconfig_port = {
+       .f = cmd_reconfig_port_parsed,
+       .data = NULL,
+       .help_str = "reconfig_port <port_id>",
+       .tokens = {
+               (void *)&cmd_reconfig_port_cmd,
+               (void *)&cmd_reconfig_port_id,
+               NULL,
+       },
+};
+
 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
 
 unsigned int
@@ -13782,6 +13812,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_read_rxd_txd,
        (cmdline_parse_inst_t *)&cmd_stop,
        (cmdline_parse_inst_t *)&cmd_reset_port,
+       (cmdline_parse_inst_t *)&cmd_reconfig_port,
        (cmdline_parse_inst_t *)&cmd_mac_addr,
        (cmdline_parse_inst_t *)&cmd_set_qmap,
        (cmdline_parse_inst_t *)&cmd_operate_port,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index da3b525..1fd6a54 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3331,3 +3331,101 @@ reset_port(portid_t port_id)
                return;
        printf("Reset port %d failed. diag=%d\n", port_id, diag);       
 }
+
+static void
+test_simplest_rxtx(portid_t port)
+{
+#define BURST_SIZE 32
+#define NUM_PACKETS 100
+
+       struct rte_mbuf *bufs[BURST_SIZE];
+       uint16_t nb_rx, nb_tx, total;
+
+       printf("Begin to forward at least %d packets to test 
reconfiguration\n", NUM_PACKETS);
+       total = 0;
+       while (1) {
+               nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
+               if (nb_rx == 0)
+                       continue;
+               nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_rx);
+               total += nb_tx;
+               /* Free any unsent packets. */
+               if (unlikely(nb_tx < nb_rx)) {
+                       uint16_t buf;
+                       for (buf = nb_tx; buf < nb_rx; buf++)
+                               rte_pktmbuf_free(bufs[buf]);
+               }
+               if (total >= NUM_PACKETS)
+                       break;
+       }
+       printf("Finish forwarding %u packets to test reconfiguration\n", total);
+       return;
+}
+
+int
+reconfig_port(portid_t port)
+{
+#define RX_RING_SIZE 128
+#define TX_RING_SIZE 512
+
+#define NUM_MBUFS 8191
+#define MBUF_CACHE_SIZE 250
+
+       struct rte_mempool *mbuf_pool;
+       struct rte_eth_conf dev_conf = {
+               .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
+       };
+       const uint16_t rx_rings = 1, tx_rings = 1;
+       int retval;
+       uint16_t q;
+
+       if (port_id_is_invalid(port, ENABLED_WARN))
+               return -1;
+
+       /* Creates a new mempool in memory to hold the mbufs. */
+       mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
+               MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, 
rte_eth_dev_socket_id(port));
+
+       /* Configure the Ethernet device. */
+       retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &dev_conf);
+       if (retval != 0)
+               return retval;
+
+       /* Allocate and set up 1 RX queue per Ethernet port. */
+       for (q = 0; q < rx_rings; q++) {
+               retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
+                               rte_eth_dev_socket_id(port), NULL, mbuf_pool);
+               if (retval < 0)
+                       return retval;
+       }
+
+       /* Allocate and set up 1 TX queue per Ethernet port. */
+       for (q = 0; q < tx_rings; q++) {
+               retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
+                               rte_eth_dev_socket_id(port), NULL);
+               if (retval < 0)
+                       return retval;
+       }
+
+       /* Start the Ethernet port. */
+       retval = rte_eth_dev_start(port);
+       if (retval < 0)
+               return retval;
+
+       /* Display the port MAC address. */
+       struct ether_addr addr;
+       rte_eth_macaddr_get(port, &addr);
+       printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
+                          " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
+                       (unsigned)port,
+                       addr.addr_bytes[0], addr.addr_bytes[1],
+                       addr.addr_bytes[2], addr.addr_bytes[3],
+                       addr.addr_bytes[4], addr.addr_bytes[5]);
+
+       /* Enable RX in promiscuous mode for the Ethernet device. */
+       rte_eth_promiscuous_enable(port);
+
+       test_simplest_rxtx(port);
+
+       return 0;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 956eec5..c4c2e59 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -599,6 +599,7 @@ void close_port(portid_t pid);
 void attach_port(char *identifier);
 void detach_port(uint8_t port_id);
 void reset_port(portid_t port_id);
+int reconfig_port(portid_t port_id);
 int all_ports_stopped(void);
 int port_is_started(portid_t port_id);
 void pmd_test_exit(void);
-- 
2.7.4

Reply via email to