app/testpmd: add or delete flow director filter
[dpdk.git] / app / test-pmd / config.c
index 52ad01a..749a23f 100644 (file)
 static void
 print_ethaddr(const char *name, struct ether_addr *eth_addr)
 {
-       printf("%s%02X:%02X:%02X:%02X:%02X:%02X", name,
-              (unsigned int)eth_addr->addr_bytes[0],
-              (unsigned int)eth_addr->addr_bytes[1],
-              (unsigned int)eth_addr->addr_bytes[2],
-              (unsigned int)eth_addr->addr_bytes[3],
-              (unsigned int)eth_addr->addr_bytes[4],
-              (unsigned int)eth_addr->addr_bytes[5]);
+       char buf[ETHER_ADDR_FMT_SIZE];
+       ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
+       printf("%s%s", name, buf);
 }
 
 void
@@ -126,19 +122,29 @@ nic_stats_display(portid_t port_id)
               nic_stats_border, port_id, nic_stats_border);
 
        if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
-               printf("  RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64"RX-bytes: "
-                      "%-"PRIu64"\n"
-                      "  TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64"TX-bytes: "
+               printf("  RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes:  "
+                      "%-"PRIu64"\n",
+                      stats.ipackets, stats.imissed, stats.ibytes);
+               printf("  RX-badcrc:  %-10"PRIu64" RX-badlen: %-10"PRIu64" RX-errors: "
+                      "%-"PRIu64"\n",
+                      stats.ibadcrc, stats.ibadlen, stats.ierrors);
+               printf("  RX-nombuf:  %-10"PRIu64"\n",
+                      stats.rx_nombuf);
+               printf("  TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes:  "
                       "%-"PRIu64"\n",
-                      stats.ipackets, stats.ierrors, stats.ibytes,
                       stats.opackets, stats.oerrors, stats.obytes);
        }
        else {
                printf("  RX-packets:              %10"PRIu64"    RX-errors: %10"PRIu64
-                      "    RX-bytes: %10"PRIu64"\n"
-                      "  TX-packets:              %10"PRIu64"    TX-errors: %10"PRIu64
+                      "    RX-bytes: %10"PRIu64"\n",
+                      stats.ipackets, stats.ierrors, stats.ibytes);
+               printf("  RX-badcrc:               %10"PRIu64"    RX-badlen: %10"PRIu64
+                      "  RX-errors:  %10"PRIu64"\n",
+                      stats.ibadcrc, stats.ibadlen, stats.ierrors);
+               printf("  RX-nombuf:               %10"PRIu64"\n",
+                      stats.rx_nombuf);
+               printf("  TX-packets:              %10"PRIu64"    TX-errors: %10"PRIu64
                       "    TX-bytes: %10"PRIu64"\n",
-                      stats.ipackets, stats.ierrors, stats.ibytes,
                       stats.opackets, stats.oerrors, stats.obytes);
        }
 
@@ -189,6 +195,40 @@ nic_stats_clear(portid_t port_id)
        printf("\n  NIC statistics for port %d cleared\n", port_id);
 }
 
+void
+nic_xstats_display(portid_t port_id)
+{
+       struct rte_eth_xstats *xstats;
+       int len, ret, i;
+
+       printf("###### NIC extended statistics for port %-2d\n", port_id);
+
+       len = rte_eth_xstats_get(port_id, NULL, 0);
+       if (len < 0) {
+               printf("Cannot get xstats count\n");
+               return;
+       }
+       xstats = malloc(sizeof(xstats[0]) * len);
+       if (xstats == NULL) {
+               printf("Cannot allocate memory for xstats\n");
+               return;
+       }
+       ret = rte_eth_xstats_get(port_id, xstats, len);
+       if (ret < 0 || ret > len) {
+               printf("Cannot get xstats\n");
+               free(xstats);
+               return;
+       }
+       for (i = 0; i < len; i++)
+               printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
+       free(xstats);
+}
+
+void
+nic_xstats_clear(portid_t port_id)
+{
+       rte_eth_xstats_reset(port_id);
+}
 
 void
 nic_stats_mapping_display(portid_t port_id)
@@ -242,7 +282,9 @@ void
 port_infos_display(portid_t port_id)
 {
        struct rte_port *port;
+       struct ether_addr mac_addr;
        struct rte_eth_link link;
+       struct rte_eth_dev_info dev_info;
        int vlan_offload;
        struct rte_mempool * mp;
        static const char *info_border = "*********************";
@@ -255,7 +297,8 @@ port_infos_display(portid_t port_id)
        rte_eth_link_get_nowait(port_id, &link);
        printf("\n%s Infos for port %-2d %s\n",
               info_border, port_id, info_border);
-       print_ethaddr("MAC address: ", &port->eth_addr);
+       rte_eth_macaddr_get(port_id, &mac_addr);
+       print_ethaddr("MAC address: ", &mac_addr);
        printf("\nConnect to socket: %u", port->socket_id);
 
        if (port_numa[port_id] != NUMA_NO_CONFIG) {
@@ -297,9 +340,14 @@ port_infos_display(portid_t port_id)
                else
                        printf("  qinq(extend) off \n");
        }
+
+       memset(&dev_info, 0, sizeof(dev_info));
+       rte_eth_dev_info_get(port_id, &dev_info);
+       if (dev_info.reta_size > 0)
+               printf("Redirection table size: %u\n", dev_info.reta_size);
 }
 
-static int
+int
 port_id_is_invalid(portid_t port_id)
 {
        if (port_id < nb_ports)
@@ -493,10 +541,23 @@ port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v)
        display_port_reg_value(port_id, reg_off, reg_v);
 }
 
+void
+port_mtu_set(portid_t port_id, uint16_t mtu)
+{
+       int diag;
+
+       if (port_id_is_invalid(port_id))
+               return;
+       diag = rte_eth_dev_set_mtu(port_id, mtu);
+       if (diag == 0)
+               return;
+       printf("Set MTU failed. diag=%d\n", diag);
+}
+
 /*
  * RX/TX ring descriptors display functions.
  */
-static int
+int
 rx_queue_id_is_invalid(queueid_t rxq_id)
 {
        if (rxq_id < nb_rxq)
@@ -505,7 +566,7 @@ rx_queue_id_is_invalid(queueid_t rxq_id)
        return 1;
 }
 
-static int
+int
 tx_queue_id_is_invalid(queueid_t txq_id)
 {
        if (txq_id < nb_txq)
@@ -540,7 +601,7 @@ ring_dma_zone_lookup(const char *ring_name, uint8_t port_id, uint16_t q_id)
        char mz_name[RTE_MEMZONE_NAMESIZE];
        const struct rte_memzone *mz;
 
-       rte_snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
+       snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
                 ports[port_id].dev_info.driver_name, ring_name, port_id, q_id);
        mz = rte_memzone_lookup(mz_name);
        if (mz == NULL)
@@ -558,23 +619,78 @@ union igb_ring_dword {
        } words;
 };
 
-struct igb_ring_desc {
+struct igb_ring_desc_32_bytes {
+       union igb_ring_dword lo_dword;
+       union igb_ring_dword hi_dword;
+       union igb_ring_dword resv1;
+       union igb_ring_dword resv2;
+};
+
+struct igb_ring_desc_16_bytes {
        union igb_ring_dword lo_dword;
        union igb_ring_dword hi_dword;
 };
 
 static void
-ring_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id)
+ring_rxd_display_dword(union igb_ring_dword dword)
+{
+       printf("    0x%08X - 0x%08X\n", (unsigned)dword.words.lo,
+                                       (unsigned)dword.words.hi);
+}
+
+static void
+ring_rx_descriptor_display(const struct rte_memzone *ring_mz,
+#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
+                          uint8_t port_id,
+#else
+                          __rte_unused uint8_t port_id,
+#endif
+                          uint16_t desc_id)
+{
+       struct igb_ring_desc_16_bytes *ring =
+               (struct igb_ring_desc_16_bytes *)ring_mz->addr;
+#ifndef RTE_LIBRTE_I40E_16BYTE_RX_DESC
+       struct rte_eth_dev_info dev_info;
+
+       memset(&dev_info, 0, sizeof(dev_info));
+       rte_eth_dev_info_get(port_id, &dev_info);
+       if (strstr(dev_info.driver_name, "i40e") != NULL) {
+               /* 32 bytes RX descriptor, i40e only */
+               struct igb_ring_desc_32_bytes *ring =
+                       (struct igb_ring_desc_32_bytes *)ring_mz->addr;
+
+               ring_rxd_display_dword(rte_le_to_cpu_64(
+                               ring[desc_id].lo_dword));
+               ring_rxd_display_dword(rte_le_to_cpu_64(
+                               ring[desc_id].hi_dword));
+               ring_rxd_display_dword(rte_le_to_cpu_64(
+                               ring[desc_id].resv1));
+               ring_rxd_display_dword(rte_le_to_cpu_64(
+                               ring[desc_id].resv2));
+               return;
+       }
+#endif
+       /* 16 bytes RX descriptor */
+       ring_rxd_display_dword(rte_le_to_cpu_64(
+                       ring[desc_id].lo_dword));
+       ring_rxd_display_dword(rte_le_to_cpu_64(
+                       ring[desc_id].hi_dword));
+}
+
+static void
+ring_tx_descriptor_display(const struct rte_memzone *ring_mz, uint16_t desc_id)
 {
-       struct igb_ring_desc *ring;
-       struct igb_ring_desc rd;
+       struct igb_ring_desc_16_bytes *ring;
+       struct igb_ring_desc_16_bytes txd;
 
-       ring = (struct igb_ring_desc *) ring_mz->addr;
-       rd.lo_dword = rte_le_to_cpu_64(ring[desc_id].lo_dword);
-       rd.hi_dword = rte_le_to_cpu_64(ring[desc_id].hi_dword);
+       ring = (struct igb_ring_desc_16_bytes *)ring_mz->addr;
+       txd.lo_dword = rte_le_to_cpu_64(ring[desc_id].lo_dword);
+       txd.hi_dword = rte_le_to_cpu_64(ring[desc_id].hi_dword);
        printf("    0x%08X - 0x%08X / 0x%08X - 0x%08X\n",
-               (unsigned)rd.lo_dword.words.lo, (unsigned)rd.lo_dword.words.hi,
-               (unsigned)rd.hi_dword.words.lo, (unsigned)rd.hi_dword.words.hi);
+                       (unsigned)txd.lo_dword.words.lo,
+                       (unsigned)txd.lo_dword.words.hi,
+                       (unsigned)txd.hi_dword.words.lo,
+                       (unsigned)txd.hi_dword.words.hi);
 }
 
 void
@@ -591,7 +707,7 @@ rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id)
        rx_mz = ring_dma_zone_lookup("rx_ring", port_id, rxq_id);
        if (rx_mz == NULL)
                return;
-       ring_descriptor_display(rx_mz, rxd_id);
+       ring_rx_descriptor_display(rx_mz, port_id, rxd_id);
 }
 
 void
@@ -608,7 +724,7 @@ tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id)
        tx_mz = ring_dma_zone_lookup("tx_ring", port_id, txq_id);
        if (tx_mz == NULL)
                return;
-       ring_descriptor_display(tx_mz, txd_id);
+       ring_tx_descriptor_display(tx_mz, txd_id);
 }
 
 void
@@ -648,36 +764,29 @@ rxtx_config_display(void)
 }
 
 void
-port_rss_reta_info(portid_t port_id,struct rte_eth_rss_reta *reta_conf)
+port_rss_reta_info(portid_t port_id,
+                  struct rte_eth_rss_reta_entry64 *reta_conf,
+                  uint16_t nb_entries)
 {
-       uint8_t i,j;
+       uint16_t i, idx, shift;
        int ret;
 
        if (port_id_is_invalid(port_id))
                return;
 
-       ret = rte_eth_dev_rss_reta_query(port_id, reta_conf);
+       ret = rte_eth_dev_rss_reta_query(port_id, reta_conf, nb_entries);
        if (ret != 0) {
                printf("Failed to get RSS RETA info, return code = %d\n", ret);
                return;
        }
 
-       if (reta_conf->mask_lo != 0) {
-               for (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
-                       if (reta_conf->mask_lo & (uint64_t)(1ULL << i))
-                               printf("RSS RETA configuration: hash index=%d,"
-                                       "queue=%d\n",i,reta_conf->reta[i]);
-               }
-       }
-
-       if (reta_conf->mask_hi != 0) {
-               for (i = 0; i< ETH_RSS_RETA_NUM_ENTRIES/2; i++) {
-                       if(reta_conf->mask_hi & (uint64_t)(1ULL << i)) {
-                               j = (uint8_t)(i + ETH_RSS_RETA_NUM_ENTRIES/2);
-                               printf("RSS RETA configuration: hash index=%d,"
-                                       "queue=%d\n",j,reta_conf->reta[j]);
-                       }
-               }
+       for (i = 0; i < nb_entries; i++) {
+               idx = i / RTE_RETA_GROUP_SIZE;
+               shift = i % RTE_RETA_GROUP_SIZE;
+               if (!(reta_conf[idx].mask & (1ULL << shift)))
+                       continue;
+               printf("RSS RETA configuration: hash index=%u, queue=%u\n",
+                                       i, reta_conf[idx].reta[shift]);
        }
 }
 
@@ -1572,6 +1681,15 @@ tx_vlan_reset(portid_t port_id)
        ports[port_id].tx_ol_flags &= ~PKT_TX_VLAN_PKT;
 }
 
+void
+tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on)
+{
+       if (port_id_is_invalid(port_id))
+               return;
+
+       rte_eth_dev_set_vlan_pvid(port_id, vlan_id, on);
+}
+
 void
 set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)
 {
@@ -1625,14 +1743,14 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)
 }
 
 void
-tx_cksum_set(portid_t port_id, uint8_t cksum_mask)
+tx_cksum_set(portid_t port_id, uint64_t ol_flags)
 {
-       uint16_t tx_ol_flags;
+       uint64_t tx_ol_flags;
        if (port_id_is_invalid(port_id))
                return;
-       /* Clear last 4 bits and then set L3/4 checksum mask again */
-       tx_ol_flags = (uint16_t) (ports[port_id].tx_ol_flags & 0xFFF0);
-       ports[port_id].tx_ol_flags = (uint16_t) ((cksum_mask & 0xf) | tx_ol_flags);
+       /* Clear last 8 bits and then set L3/4 checksum mask again */
+       tx_ol_flags = ports[port_id].tx_ol_flags & (~0x0FFull);
+       ports[port_id].tx_ol_flags = ((ol_flags & 0xff) | tx_ol_flags);
 }
 
 void
@@ -1871,3 +1989,150 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
        return diag;
 }
 
+void
+get_ethertype_filter(uint8_t port_id, uint16_t index)
+{
+       struct rte_ethertype_filter filter;
+       int ret = 0;
+       uint16_t rx_queue;
+
+       memset(&filter, 0, sizeof(filter));
+       ret = rte_eth_dev_get_ethertype_filter(port_id, index,
+                               &filter, &rx_queue);
+       if (ret < 0) {
+               if (ret == (-ENOENT))
+                       printf("filter[%d] is not enabled\n", index);
+               else
+                       printf("get ethertype filter fails(%s)\n", strerror(-ret));
+               return;
+       } else {
+               printf("filter[%d]:\n", index);
+               printf("    ethertype:  0x%04x\n",
+                       rte_le_to_cpu_32(filter.ethertype));
+               printf("    priority: %s, %d\n",
+                       filter.priority_en ? "enable" : "disable",
+                       filter.priority);
+               printf("    queue: %d\n", rx_queue);
+       }
+}
+
+void
+get_syn_filter(uint8_t port_id)
+{
+       struct rte_syn_filter filter;
+       int ret = 0;
+       uint16_t rx_queue;
+
+       memset(&filter, 0, sizeof(filter));
+       ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue);
+
+       if (ret < 0) {
+               if (ret == (-ENOENT))
+                       printf("syn filter is not enabled\n");
+               else
+                       printf("get syn filter fails(%s)\n", strerror(-ret));
+               return;
+       }
+       printf("syn filter: priority: %s, queue: %d\n",
+               filter.hig_pri ? "high" : "low",
+               rx_queue);
+}
+void
+get_2tuple_filter(uint8_t port_id, uint16_t index)
+{
+       struct rte_2tuple_filter filter;
+       int ret = 0;
+       uint16_t rx_queue;
+
+       memset(&filter, 0, sizeof(filter));
+       ret = rte_eth_dev_get_2tuple_filter(port_id, index,
+                               &filter, &rx_queue);
+       if (ret < 0) {
+               if (ret == (-ENOENT))
+                       printf("filter[%d] is not enabled\n", index);
+               else
+                       printf("get 2tuple filter fails(%s)\n", strerror(-ret));
+               return;
+       } else {
+               printf("filter[%d]:\n", index);
+               printf("    Destination Port:     0x%04x    mask: %d\n",
+                       rte_be_to_cpu_16(filter.dst_port),
+                       filter.dst_port_mask ? 0 : 1);
+               printf("    protocol:  0x%02x     mask:%d     tcp_flags: 0x%02x\n",
+                       filter.protocol, filter.protocol_mask ? 0 : 1,
+                       filter.tcp_flags);
+               printf("    priority: %d    queue: %d\n",
+                       filter.priority, rx_queue);
+       }
+}
+
+void
+get_5tuple_filter(uint8_t port_id, uint16_t index)
+{
+       struct rte_5tuple_filter filter;
+       int ret = 0;
+       uint16_t rx_queue;
+
+       memset(&filter, 0, sizeof(filter));
+       ret = rte_eth_dev_get_5tuple_filter(port_id, index,
+                               &filter, &rx_queue);
+       if (ret < 0) {
+               if (ret == (-ENOENT))
+                       printf("filter[%d] is not enabled\n", index);
+               else
+                       printf("get 5tuple filter fails(%s)\n", strerror(-ret));
+               return;
+       } else {
+               printf("filter[%d]:\n", index);
+               printf("    Destination IP:  0x%08x    mask: %d\n",
+                       (unsigned)rte_be_to_cpu_32(filter.dst_ip),
+                       filter.dst_ip_mask ? 0 : 1);
+               printf("    Source IP:       0x%08x    mask: %d\n",
+                       (unsigned)rte_be_to_cpu_32(filter.src_ip),
+                       filter.src_ip_mask ? 0 : 1);
+               printf("    Destination Port:       0x%04x    mask: %d\n",
+                       rte_be_to_cpu_16(filter.dst_port),
+                       filter.dst_port_mask ? 0 : 1);
+               printf("    Source Port:       0x%04x    mask: %d\n",
+                       rte_be_to_cpu_16(filter.src_port),
+                       filter.src_port_mask ? 0 : 1);
+               printf("    protocol:           0x%02x    mask: %d\n",
+                       filter.protocol,
+                       filter.protocol_mask ? 0 : 1);
+               printf("    priority: %d    flags: 0x%02x    queue: %d\n",
+                       filter.priority, filter.tcp_flags, rx_queue);
+       }
+}
+void
+get_flex_filter(uint8_t port_id, uint16_t index)
+
+{
+       struct rte_flex_filter filter;
+       int ret = 0;
+       uint16_t rx_queue;
+       int i, j;
+
+       memset(&filter, 0, sizeof(filter));
+       ret = rte_eth_dev_get_flex_filter(port_id, index,
+                               &filter, &rx_queue);
+       if (ret < 0) {
+               if (ret == (-ENOENT))
+                       printf("filter[%d] is not enabled\n", index);
+               else
+                       printf("get flex filter fails(%s)\n", strerror(-ret));
+               return;
+       } else {
+               printf("filter[%d]: ", index);
+               printf("\n    length: %d", filter.len);
+               printf("\n    dword[]: 0x");
+               for (i = 0; i < 32; i++)
+                       printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i]));
+               printf("\n    mask[]: 0b");
+               for (i = 0; i < 16; i++) {
+                       for (j = 0; j < 8; j++)
+                               printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0');
+               }
+               printf("\n    priority: %d    queue: %d\n",
+                       filter.priority, rx_queue);
+       }
+}