net/mlx5: limit priority range for Linux TC flower driver
[dpdk.git] / app / test-pmd / testpmd.c
index dd6e6ea..9c0edca 100644 (file)
@@ -345,6 +345,24 @@ uint8_t rmv_interrupt = 1; /* enabled by default */
 
 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
 
+/* After attach, port setup is called on event or by iterator */
+bool setup_on_probe_event = true;
+
+/* Pretty printing of ethdev events */
+static const char * const eth_event_desc[] = {
+       [RTE_ETH_EVENT_UNKNOWN] = "unknown",
+       [RTE_ETH_EVENT_INTR_LSC] = "link state change",
+       [RTE_ETH_EVENT_QUEUE_STATE] = "queue state",
+       [RTE_ETH_EVENT_INTR_RESET] = "reset",
+       [RTE_ETH_EVENT_VF_MBOX] = "VF mbox",
+       [RTE_ETH_EVENT_IPSEC] = "IPsec",
+       [RTE_ETH_EVENT_MACSEC] = "MACsec",
+       [RTE_ETH_EVENT_INTR_RMV] = "device removal",
+       [RTE_ETH_EVENT_NEW] = "device probed",
+       [RTE_ETH_EVENT_DESTROY] = "device released",
+       [RTE_ETH_EVENT_MAX] = NULL,
+};
+
 /*
  * Display or mask ether events
  * Default to all events except VF_MBOX
@@ -1939,7 +1957,6 @@ start_port(portid_t pid)
        queueid_t qi;
        struct rte_port *port;
        struct ether_addr mac_addr;
-       enum rte_eth_event_type event_type;
 
        if (port_id_is_invalid(pid, ENABLED_WARN))
                return 0;
@@ -2095,20 +2112,6 @@ start_port(portid_t pid)
                need_check_link_status = 1;
        }
 
-       for (event_type = RTE_ETH_EVENT_UNKNOWN;
-            event_type < RTE_ETH_EVENT_MAX;
-            event_type++) {
-               diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
-                                               event_type,
-                                               eth_event_callback,
-                                               NULL);
-               if (diag) {
-                       printf("Failed to setup even callback for event %d\n",
-                               event_type);
-                       return -1;
-               }
-       }
-
        if (need_check_link_status == 1 && !no_link_check)
                check_all_ports_link_status(RTE_PORT_ALL);
        else if (need_check_link_status == 0)
@@ -2285,7 +2288,7 @@ reset_port(portid_t pid)
 void
 attach_port(char *identifier)
 {
-       portid_t pi = 0;
+       portid_t pi;
        struct rte_dev_iterator iterator;
 
        printf("Attaching a new port...\n");
@@ -2300,8 +2303,23 @@ attach_port(char *identifier)
                return;
        }
 
-       RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator)
+       /* first attach mode: event */
+       if (setup_on_probe_event) {
+               /* new ports are detected on RTE_ETH_EVENT_NEW event */
+               for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++)
+                       if (ports[pi].port_status == RTE_PORT_HANDLING &&
+                                       ports[pi].need_setup != 0)
+                               setup_attached_port(pi);
+               return;
+       }
+
+       /* second attach mode: iterator */
+       RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator) {
+               /* setup ports matching the devargs used for probing */
+               if (port_is_forwarding(pi))
+                       continue; /* port was already attached before */
                setup_attached_port(pi);
+       }
 }
 
 static void
@@ -2319,6 +2337,7 @@ setup_attached_port(portid_t pi)
        ports_ids[nb_ports++] = pi;
        fwd_ports_ids[nb_fwd_ports++] = pi;
        nb_cfg_ports = nb_fwd_ports;
+       ports[pi].need_setup = 0;
        ports[pi].port_status = RTE_PORT_STOPPED;
 
        printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
@@ -2524,20 +2543,6 @@ static int
 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
                  void *ret_param)
 {
-       static const char * const event_desc[] = {
-               [RTE_ETH_EVENT_UNKNOWN] = "Unknown",
-               [RTE_ETH_EVENT_INTR_LSC] = "LSC",
-               [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
-               [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
-               [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
-               [RTE_ETH_EVENT_IPSEC] = "IPsec",
-               [RTE_ETH_EVENT_MACSEC] = "MACsec",
-               [RTE_ETH_EVENT_INTR_RMV] = "device removal",
-               [RTE_ETH_EVENT_NEW] = "device probed",
-               [RTE_ETH_EVENT_DESTROY] = "device released",
-               [RTE_ETH_EVENT_MAX] = NULL,
-       };
-
        RTE_SET_USED(param);
        RTE_SET_USED(ret_param);
 
@@ -2547,15 +2552,18 @@ eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
                fflush(stderr);
        } else if (event_print_mask & (UINT32_C(1) << type)) {
                printf("\nPort %" PRIu16 ": %s event\n", port_id,
-                       event_desc[type]);
+                       eth_event_desc[type]);
                fflush(stdout);
        }
 
-       if (port_id_is_invalid(port_id, DISABLED_WARN))
-               return 0;
-
        switch (type) {
+       case RTE_ETH_EVENT_NEW:
+               ports[port_id].need_setup = 1;
+               ports[port_id].port_status = RTE_PORT_HANDLING;
+               break;
        case RTE_ETH_EVENT_INTR_RMV:
+               if (port_id_is_invalid(port_id, DISABLED_WARN))
+                       break;
                if (rte_eal_alarm_set(100000,
                                rmv_event_callback, (void *)(intptr_t)port_id))
                        fprintf(stderr, "Could not set up deferred device removal\n");
@@ -2566,6 +2574,28 @@ eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
        return 0;
 }
 
+static int
+register_eth_event_callback(void)
+{
+       int ret;
+       enum rte_eth_event_type event;
+
+       for (event = RTE_ETH_EVENT_UNKNOWN;
+                       event < RTE_ETH_EVENT_MAX; event++) {
+               ret = rte_eth_dev_callback_register(RTE_ETH_ALL,
+                               event,
+                               eth_event_callback,
+                               NULL);
+               if (ret != 0) {
+                       TESTPMD_LOG(ERR, "Failed to register callback for "
+                                       "%s event\n", eth_event_desc[event]);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 /* This function is used by the interrupt thread */
 static void
 eth_dev_event_callback(const char *device_name, enum rte_dev_event_type type,
@@ -3050,6 +3080,10 @@ main(int argc, char** argv)
                rte_panic("Cannot register log type");
        rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
 
+       ret = register_eth_event_callback();
+       if (ret != 0)
+               rte_panic("Cannot register for ethdev events");
+
 #ifdef RTE_LIBRTE_PDUMP
        /* initialize packet capture framework */
        rte_pdump_init(NULL);