app/testpmd: add option to not start device
[dpdk.git] / app / test-pmd / testpmd.c
index c578f75..518865a 100644 (file)
@@ -339,6 +339,11 @@ uint8_t flow_isolate_all;
  */
 uint8_t no_link_check = 0; /* check by default */
 
+/*
+ * Don't automatically start all ports in interactive mode.
+ */
+uint8_t no_device_start = 0;
+
 /*
  * Enable link status change notification
  */
@@ -2475,6 +2480,51 @@ detach_port_device(portid_t port_id)
        return;
 }
 
+void
+detach_device(char *identifier)
+{
+       struct rte_dev_iterator iterator;
+       struct rte_devargs da;
+       portid_t port_id;
+
+       printf("Removing a device...\n");
+
+       memset(&da, 0, sizeof(da));
+       if (rte_devargs_parsef(&da, "%s", identifier)) {
+               printf("cannot parse identifier\n");
+               if (da.args)
+                       free(da.args);
+               return;
+       }
+
+       RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) {
+               if (ports[port_id].port_status != RTE_PORT_CLOSED) {
+                       if (ports[port_id].port_status != RTE_PORT_STOPPED) {
+                               printf("Port %u not stopped\n", port_id);
+                               return;
+                       }
+
+                       /* sibling ports are forced to be closed */
+                       if (ports[port_id].flow_list)
+                               port_flow_flush(port_id);
+                       ports[port_id].port_status = RTE_PORT_CLOSED;
+                       printf("Port %u is now closed\n", port_id);
+               }
+       }
+
+       if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) {
+               TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n",
+                           da.name, da.bus->name);
+               return;
+       }
+
+       remove_invalid_ports();
+
+       printf("Device %s is detached\n", identifier);
+       printf("Now total ports is %d\n", nb_ports);
+       printf("Done\n");
+}
+
 void
 pmd_test_exit(void)
 {
@@ -2824,7 +2874,8 @@ rxtx_port_config(struct rte_port *port)
        for (qid = 0; qid < nb_rxq; qid++) {
                offloads = port->rx_conf[qid].offloads;
                port->rx_conf[qid] = port->dev_info.default_rxconf;
-               port->rx_conf[qid].offloads |= offloads;
+               if (offloads != 0)
+                       port->rx_conf[qid].offloads = offloads;
 
                /* Check if any Rx parameters have been passed */
                if (rx_pthresh != RTE_PMD_PARAM_UNSET)
@@ -2848,7 +2899,8 @@ rxtx_port_config(struct rte_port *port)
        for (qid = 0; qid < nb_txq; qid++) {
                offloads = port->tx_conf[qid].offloads;
                port->tx_conf[qid] = port->dev_info.default_txconf;
-               port->tx_conf[qid].offloads |= offloads;
+               if (offloads != 0)
+                       port->tx_conf[qid].offloads = offloads;
 
                /* Check if any Tx parameters have been passed */
                if (tx_pthresh != RTE_PMD_PARAM_UNSET)
@@ -3286,7 +3338,7 @@ main(int argc, char** argv)
                }
        }
 
-       if (start_port(RTE_PORT_ALL) != 0)
+       if (!no_device_start && start_port(RTE_PORT_ALL) != 0)
                rte_exit(EXIT_FAILURE, "Start ports failed\n");
 
        /* set all ports to promiscuous mode by default */