ethdev: fix max Rx packet length
[dpdk.git] / examples / l3fwd / main.c
index 518fefe..7701302 100644 (file)
@@ -120,7 +120,6 @@ static uint16_t nb_lcore_params = sizeof(lcore_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,
        },
@@ -135,6 +134,8 @@ static struct rte_eth_conf port_conf = {
        },
 };
 
+static uint32_t max_pkt_len;
+
 static struct rte_mempool *pktmbuf_pool[RTE_MAX_ETHPORTS][NB_SOCKETS];
 static uint8_t lkp_per_socket[NB_SOCKETS];
 
@@ -325,7 +326,7 @@ print_usage(const char *prgname)
                " [--lookup]"
                " --config (port,queue,lcore)[,(port,queue,lcore)]"
                " [--eth-dest=X,MM:MM:MM:MM:MM:MM]"
-               " [--enable-jumbo [--max-pkt-len PKTLEN]]"
+               " [--max-pkt-len PKTLEN]"
                " [--no-numa]"
                " [--hash-entry-num]"
                " [--ipv6]"
@@ -343,9 +344,7 @@ print_usage(const char *prgname)
                "            Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base)\n"
                "  --config (port,queue,lcore): Rx queue configuration\n"
                "  --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for port X\n"
-               "  --enable-jumbo: Enable jumbo frames\n"
-               "  --max-pkt-len: Under the premise of enabling jumbo,\n"
-               "                 maximum packet length in decimal (64-9600)\n"
+               "  --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n"
                "  --no-numa: Disable numa awareness\n"
                "  --hash-entry-num: Specify the hash entry number in hexadecimal to be setup\n"
                "  --ipv6: Set if running ipv6 packets\n"
@@ -565,7 +564,7 @@ static const char short_options[] =
 #define CMD_LINE_OPT_ETH_DEST "eth-dest"
 #define CMD_LINE_OPT_NO_NUMA "no-numa"
 #define CMD_LINE_OPT_IPV6 "ipv6"
-#define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
+#define CMD_LINE_OPT_MAX_PKT_LEN "max-pkt-len"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
 #define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 #define CMD_LINE_OPT_PER_PORT_POOL "per-port-pool"
@@ -583,7 +582,7 @@ enum {
        CMD_LINE_OPT_ETH_DEST_NUM,
        CMD_LINE_OPT_NO_NUMA_NUM,
        CMD_LINE_OPT_IPV6_NUM,
-       CMD_LINE_OPT_ENABLE_JUMBO_NUM,
+       CMD_LINE_OPT_MAX_PKT_LEN_NUM,
        CMD_LINE_OPT_HASH_ENTRY_NUM_NUM,
        CMD_LINE_OPT_PARSE_PTYPE_NUM,
        CMD_LINE_OPT_PARSE_PER_PORT_POOL,
@@ -598,7 +597,7 @@ static const struct option lgopts[] = {
        {CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM},
        {CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM},
        {CMD_LINE_OPT_IPV6, 0, 0, CMD_LINE_OPT_IPV6_NUM},
-       {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, CMD_LINE_OPT_ENABLE_JUMBO_NUM},
+       {CMD_LINE_OPT_MAX_PKT_LEN, 1, 0, CMD_LINE_OPT_MAX_PKT_LEN_NUM},
        {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, CMD_LINE_OPT_HASH_ENTRY_NUM_NUM},
        {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, CMD_LINE_OPT_PARSE_PTYPE_NUM},
        {CMD_LINE_OPT_PER_PORT_POOL, 0, 0, CMD_LINE_OPT_PARSE_PER_PORT_POOL},
@@ -697,31 +696,9 @@ parse_args(int argc, char **argv)
                        ipv6 = 1;
                        break;
 
-               case CMD_LINE_OPT_ENABLE_JUMBO_NUM: {
-                       const struct option lenopts = {
-                               "max-pkt-len", required_argument, 0, 0
-                       };
-
-                       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) {
-                                       fprintf(stderr,
-                                               "invalid maximum packet length\n");
-                                       print_usage(prgname);
-                                       return -1;
-                               }
-                               port_conf.rxmode.max_rx_pkt_len = ret;
-                       }
+               case CMD_LINE_OPT_MAX_PKT_LEN_NUM:
+                       max_pkt_len = parse_max_pkt_len(optarg);
                        break;
-               }
 
                case CMD_LINE_OPT_HASH_ENTRY_NUM_NUM:
                        ret = parse_hash_entry_number(optarg);
@@ -980,6 +957,43 @@ prepare_ptype_parser(uint16_t portid, uint16_t queueid)
        return 0;
 }
 
+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;
+}
+
 static void
 l3fwd_poll_resource_setup(void)
 {
@@ -1034,6 +1048,12 @@ l3fwd_poll_resource_setup(void)
                                "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;