+static int
+all_ports_started(void)
+{
+ portid_t pi;
+ struct rte_port *port;
+
+ for (pi = 0; pi < nb_ports; pi++) {
+ port = &ports[pi];
+ /* Check if there is a port which is not started */
+ if (port->port_status != RTE_PORT_STARTED)
+ return 0;
+ }
+
+ /* No port is not started */
+ return 1;
+}
+
+void
+start_port(portid_t pid)
+{
+ int diag, need_check_link_status = 0;
+ portid_t pi;
+ queueid_t qi;
+ struct rte_port *port;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+
+ if (init_fwd_streams() < 0) {
+ printf("Fail from init_fwd_streams()\n");
+ return;
+ }
+
+ if(dcb_config)
+ dcb_test = 1;
+ for (pi = 0; pi < nb_ports; pi++) {
+ if (pid < nb_ports && pid != pi)
+ continue;
+
+ port = &ports[pi];
+ if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
+ RTE_PORT_HANDLING) == 0) {
+ printf("Port %d is now not stopped\n", pi);
+ continue;
+ }
+
+ if (port->need_reconfig > 0) {
+ port->need_reconfig = 0;
+
+ printf("Configuring Port %d\n", pi);
+ /* configure port */
+ diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
+ &(port->dev_conf));
+ if (diag != 0) {
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back "
+ "to stopped\n", pi);
+ printf("Fail to configure port %d\n", pi);
+ /* try to reconfigure port next time */
+ port->need_reconfig = 1;
+ return;
+ }
+ }
+
+ if (port->need_reconfig_queues > 0) {
+ port->need_reconfig_queues = 0;
+
+ /* setup tx queues */
+ for (qi = 0; qi < nb_txq; qi++) {
+ diag = rte_eth_tx_queue_setup(pi, qi, nb_txd,
+ port->socket_id, &(port->tx_conf));
+ if (diag == 0)
+ continue;
+
+ /* Fail to setup tx queue, return */
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING,
+ RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back "
+ "to stopped\n", pi);
+ printf("Fail to configure port %d tx queues\n", pi);
+ /* try to reconfigure queues next time */
+ port->need_reconfig_queues = 1;
+ return;
+ }
+ /* setup rx queues */
+ for (qi = 0; qi < nb_rxq; qi++) {
+ diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd,
+ port->socket_id, &(port->rx_conf),
+ mbuf_pool_find(port->socket_id));
+ if (diag == 0)
+ continue;
+
+ /* Fail to setup rx queue, return */
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING,
+ RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back "
+ "to stopped\n", pi);
+ printf("Fail to configure port %d rx queues\n", pi);
+ /* try to reconfigure queues next time */
+ port->need_reconfig_queues = 1;
+ return;
+ }
+ }
+
+ /* start port */
+ if (rte_eth_dev_start(pi) < 0) {
+ printf("Fail to start port %d\n", pi);
+
+ /* Fail to setup rx queue, return */
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set back to "
+ "stopped\n", pi);
+ continue;
+ }
+
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
+ printf("Port %d can not be set into started\n", pi);
+
+ /* at least one port started, need checking link status */
+ need_check_link_status = 1;
+ }
+
+ if (need_check_link_status)
+ check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
+ else
+ printf("Please stop the ports first\n");
+
+ printf("Done\n");
+}
+
+void
+stop_port(portid_t pid)
+{
+ portid_t pi;
+ struct rte_port *port;
+ int need_check_link_status = 0;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+ if (dcb_test) {
+ dcb_test = 0;
+ dcb_config = 0;
+ }
+ printf("Stopping ports...\n");
+
+ for (pi = 0; pi < nb_ports; pi++) {
+ if (pid < nb_ports && pid != pi)
+ continue;
+
+ port = &ports[pi];
+ if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
+ RTE_PORT_HANDLING) == 0)
+ continue;
+
+ rte_eth_dev_stop(pi);
+
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
+ printf("Port %d can not be set into stopped\n", pi);
+ need_check_link_status = 1;
+ }
+ if (need_check_link_status)
+ check_all_ports_link_status(nb_ports, RTE_PORT_ALL);
+
+ printf("Done\n");
+}
+
+void
+close_port(portid_t pid)
+{
+ portid_t pi;
+ struct rte_port *port;
+
+ if (test_done == 0) {
+ printf("Please stop forwarding first\n");
+ return;
+ }
+
+ printf("Closing ports...\n");
+
+ for (pi = 0; pi < nb_ports; pi++) {
+ if (pid < nb_ports && pid != pi)
+ continue;
+
+ port = &ports[pi];
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
+ printf("Port %d is now not stopped\n", pi);
+ continue;
+ }
+
+ rte_eth_dev_close(pi);
+
+ if (rte_atomic16_cmpset(&(port->port_status),
+ RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
+ printf("Port %d can not be set into stopped\n", pi);
+ }
+
+ printf("Done\n");
+}
+
+int
+all_ports_stopped(void)
+{
+ portid_t pi;
+ struct rte_port *port;
+
+ for (pi = 0; pi < nb_ports; pi++) {
+ port = &ports[pi];
+ if (port->port_status != RTE_PORT_STOPPED)
+ return 0;
+ }
+
+ return 1;
+}
+