ethdev: fix max Rx packet length
[dpdk.git] / examples / performance-thread / l3fwd-thread / main.c
index 50ecc4e..69a1220 100644 (file)
@@ -307,7 +307,6 @@ static uint16_t nb_tx_thread_params = RTE_DIM(tx_thread_params_array_default);
 static struct rte_eth_conf port_conf = {
        .rxmode = {
                .mq_mode = ETH_MQ_RX_RSS,
-               .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
                .split_hdr_size = 0,
                .offloads = DEV_RX_OFFLOAD_CHECKSUM,
        },
@@ -322,6 +321,8 @@ static struct rte_eth_conf port_conf = {
        },
 };
 
+static uint32_t max_pkt_len;
+
 static struct rte_mempool *pktmbuf_pool[NB_SOCKETS];
 
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
@@ -2639,7 +2640,7 @@ print_usage(const char *prgname)
        printf("%s [EAL options] -- -p PORTMASK -P"
                "  [--rx (port,queue,lcore,thread)[,(port,queue,lcore,thread]]"
                "  [--tx (lcore,thread)[,(lcore,thread]]"
-               "  [--enable-jumbo [--max-pkt-len PKTLEN]]\n"
+               "  [--max-pkt-len PKTLEN]"
                "  [--parse-ptype]\n\n"
                "  -p PORTMASK: hexadecimal bitmask of ports to configure\n"
                "  -P : enable promiscuous mode\n"
@@ -2649,8 +2650,7 @@ print_usage(const char *prgname)
                "  --eth-dest=X,MM:MM:MM:MM:MM:MM: optional, ethernet destination for port X\n"
                "  --no-numa: optional, disable numa awareness\n"
                "  --ipv6: optional, specify it if running ipv6 packets\n"
-               "  --enable-jumbo: enable jumbo frame"
-               " which max packet len is PKTLEN in decimal (64-9600)\n"
+               "  --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n"
                "  --hash-entry-num: specify the hash entry number in hexadecimal to be setup\n"
                "  --no-lthreads: turn off lthread model\n"
                "  --parse-ptype: set to use software to analyze packet type\n\n",
@@ -2873,8 +2873,8 @@ enum {
        OPT_NO_NUMA_NUM,
 #define OPT_IPV6            "ipv6"
        OPT_IPV6_NUM,
-#define OPT_ENABLE_JUMBO    "enable-jumbo"
-       OPT_ENABLE_JUMBO_NUM,
+#define OPT_MAX_PKT_LEN "max-pkt-len"
+       OPT_MAX_PKT_LEN_NUM,
 #define OPT_HASH_ENTRY_NUM  "hash-entry-num"
        OPT_HASH_ENTRY_NUM_NUM,
 #define OPT_NO_LTHREADS     "no-lthreads"
@@ -2898,7 +2898,7 @@ parse_args(int argc, char **argv)
                {OPT_ETH_DEST,       1, NULL, OPT_ETH_DEST_NUM       },
                {OPT_NO_NUMA,        0, NULL, OPT_NO_NUMA_NUM        },
                {OPT_IPV6,           0, NULL, OPT_IPV6_NUM           },
-               {OPT_ENABLE_JUMBO,   0, NULL, OPT_ENABLE_JUMBO_NUM   },
+               {OPT_MAX_PKT_LEN,    1, NULL, OPT_MAX_PKT_LEN_NUM    },
                {OPT_HASH_ENTRY_NUM, 1, NULL, OPT_HASH_ENTRY_NUM_NUM },
                {OPT_NO_LTHREADS,    0, NULL, OPT_NO_LTHREADS_NUM    },
                {OPT_PARSE_PTYPE,    0, NULL, OPT_PARSE_PTYPE_NUM    },
@@ -2977,35 +2977,10 @@ parse_args(int argc, char **argv)
                        parse_ptype_on = 1;
                        break;
 
-               case OPT_ENABLE_JUMBO_NUM:
-               {
-                       struct option lenopts = {"max-pkt-len",
-                                       required_argument, 0, 0};
-
-                       printf("jumbo frame is enabled - disabling simple TX path\n");
-                       port_conf.rxmode.offloads |=
-                                       DEV_RX_OFFLOAD_JUMBO_FRAME;
-                       port_conf.txmode.offloads |=
-                                       DEV_TX_OFFLOAD_MULTI_SEGS;
-
-                       /* if no max-pkt-len set, use the default value
-                        * RTE_ETHER_MAX_LEN
-                        */
-                       if (getopt_long(argc, argvopt, "", &lenopts,
-                                       &option_index) == 0) {
-
-                               ret = parse_max_pkt_len(optarg);
-                               if ((ret < 64) || (ret > MAX_JUMBO_PKT_LEN)) {
-                                       printf("invalid packet length\n");
-                                       print_usage(prgname);
-                                       return -1;
-                               }
-                               port_conf.rxmode.max_rx_pkt_len = ret;
-                       }
-                       printf("set jumbo frame max packet length to %u\n",
-                               (unsigned int)port_conf.rxmode.max_rx_pkt_len);
+               case OPT_MAX_PKT_LEN_NUM:
+                       max_pkt_len = parse_max_pkt_len(optarg);
                        break;
-               }
+
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
                case OPT_HASH_ENTRY_NUM_NUM:
                        ret = parse_hash_entry_number(optarg);
@@ -3485,6 +3460,43 @@ check_all_ports_link_status(uint32_t port_mask)
        }
 }
 
+static uint32_t
+eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu)
+{
+       uint32_t overhead_len;
+
+       if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu)
+               overhead_len = max_rx_pktlen - max_mtu;
+       else
+               overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
+
+       return overhead_len;
+}
+
+static int
+config_port_max_pkt_len(struct rte_eth_conf *conf,
+               struct rte_eth_dev_info *dev_info)
+{
+       uint32_t overhead_len;
+
+       if (max_pkt_len == 0)
+               return 0;
+
+       if (max_pkt_len < RTE_ETHER_MIN_LEN || max_pkt_len > MAX_JUMBO_PKT_LEN)
+               return -1;
+
+       overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen,
+                       dev_info->max_mtu);
+       conf->rxmode.mtu = max_pkt_len - overhead_len;
+
+       if (conf->rxmode.mtu > RTE_ETHER_MTU) {
+               conf->txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
+               conf->rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
+       }
+
+       return 0;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -3573,6 +3585,12 @@ main(int argc, char **argv)
                                "Error during getting device (port %u) info: %s\n",
                                portid, strerror(-ret));
 
+               ret = config_port_max_pkt_len(&local_port_conf, &dev_info);
+               if (ret != 0)
+                       rte_exit(EXIT_FAILURE,
+                               "Invalid max packet length: %u (port %u)\n",
+                               max_pkt_len, portid);
+
                if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
                        local_port_conf.txmode.offloads |=
                                DEV_TX_OFFLOAD_MBUF_FAST_FREE;