app/testpmd: add vlan offload support
authorIntel <intel.com>
Wed, 19 Dec 2012 23:00:00 +0000 (00:00 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Thu, 25 Jul 2013 13:54:18 +0000 (15:54 +0200)
Signed-off-by: Intel
app/test-pmd/cmdline.c
app/test-pmd/config.c
app/test-pmd/parameters.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h

index 6142c15..2c82098 100644 (file)
@@ -135,13 +135,16 @@ static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
                       "- set corelist|portlist x[,y]*\n"
                       "    Set the list of forwarding cores / forwarding "
                       "ports\n"
+                      "- vlan set strip|filter|qinq on/off port_id\n"
+                      "    Set the VLAN strip, filter, QinQ(extended) on a port"
                       "- rx_vlan add/rm vlan_id|all port_id\n"
-                      "    Add/remove vlan_id, or all identifiers, to/from "
-                      "the set of VLAN Identifiers\n    filtered by port_id\n"
+                      "    Set the VLAN filter table, add/remove vlan_id, or all "
+                      "identifiers, to/from the set of VLAN Identifiers\n"
+                      "filtered by port_id\n"
+                      "- rx_vlan set tpid value port_id\n"
+                      "    Set Outer VLAN TPID for Packet Filtering on a port \n"
                       "- tx_vlan set vlan_id port_id\n"
-                      "    Enable hardware insertion of a VLAN header with "
-                      "the Tag Identifier vlan_id\n    in packets sent on"
-                      "port_id\n"
+                      "    Set hardware insertion of VLAN ID in packets sent on a port\n"
                       "- tx_vlan reset port_id\n"
                       "    Disable hardware insertion of a VLAN header in "
                       "packets sent on port_id\n"
@@ -564,6 +567,153 @@ cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
        },
 };
 
+/* *** VLAN OFFLOAD SET ON A PORT *** */
+struct cmd_vlan_offload_result {
+       cmdline_fixed_string_t vlan;
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t what;
+       cmdline_fixed_string_t on;
+       cmdline_fixed_string_t port_id;
+};
+
+static void
+cmd_vlan_offload_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       int on;
+       struct cmd_vlan_offload_result *res = parsed_result;    
+       char *str;
+       int i, len = 0;
+       portid_t port_id = 0;
+       unsigned int tmp;
+       
+       str = res->port_id;
+       len = strnlen(str, STR_TOKEN_SIZE);
+       i = 0;
+       /* Get port_id first */
+       while(i < len){
+               if(str[i] == ',')
+                       break;
+               
+               i++;
+       }
+       str[i]='\0';
+       tmp = strtoul(str, NULL, 0);
+       /* If port_id greater that what portid_t can represent, return */
+       if(tmp > 255)
+               return;
+       port_id = (portid_t)tmp;
+
+       if (!strcmp(res->on, "on"))
+               on = 1;
+       else
+               on = 0;
+
+       if (!strcmp(res->what, "strip"))
+               rx_vlan_strip_set(port_id,  on);
+       else if(!strcmp(res->what, "stripq")){
+               uint16_t queue_id = 0;
+
+               /* No queue_id, return */
+               if(i + 1 >= len)
+                       return;
+               tmp = strtoul(str + i + 1, NULL, 0);
+               /* If queue_id greater that what 16-bits can represent, return */
+               if(tmp > 0xffff)
+                       return;
+               
+               queue_id = (uint16_t)tmp;
+               rx_vlan_strip_set_on_queue(port_id, queue_id, on);
+       }
+       else if (!strcmp(res->what, "filter"))
+               rx_vlan_filter_set(port_id, on);
+       else
+               vlan_extend_set(port_id, on);
+
+       return;
+}
+
+cmdline_parse_token_string_t cmd_vlan_offload_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+                                vlan, "vlan");
+cmdline_parse_token_string_t cmd_vlan_offload_set =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+                                set, "set");
+cmdline_parse_token_string_t cmd_vlan_offload_what =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+                                what, "strip#filter#qinq#stripq");
+cmdline_parse_token_string_t cmd_vlan_offload_on =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+                             on, "on#off");
+cmdline_parse_token_string_t cmd_vlan_offload_portid =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
+                             port_id, NULL);
+
+cmdline_parse_inst_t cmd_vlan_offload = {
+       .f = cmd_vlan_offload_parsed,
+       .data = NULL,
+       .help_str = "set strip|filter|qinq|stripq on|off port_id[,queue_id], filter/strip for rx side"
+       " qinq(extended) for both rx/tx sides ",
+       .tokens = {
+               (void *)&cmd_vlan_offload_vlan,
+               (void *)&cmd_vlan_offload_set,
+               (void *)&cmd_vlan_offload_what,
+               (void *)&cmd_vlan_offload_on,
+               (void *)&cmd_vlan_offload_portid,
+               NULL,
+       },
+};
+
+/* *** VLAN TPID SET ON A PORT *** */
+struct cmd_vlan_tpid_result {
+       cmdline_fixed_string_t vlan;
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t what;
+       uint16_t tp_id;
+       uint8_t port_id;
+};
+
+static void
+cmd_vlan_tpid_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_vlan_tpid_result *res = parsed_result;
+       vlan_tpid_set(res->port_id, res->tp_id);
+       return;
+}
+
+cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+                                vlan, "vlan");
+cmdline_parse_token_string_t cmd_vlan_tpid_set =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+                                set, "set");
+cmdline_parse_token_string_t cmd_vlan_tpid_what =
+       TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
+                                what, "tpid");
+cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
+       TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
+                             tp_id, UINT16);
+cmdline_parse_token_num_t cmd_vlan_tpid_portid =
+       TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
+                             port_id, UINT8);
+
+cmdline_parse_inst_t cmd_vlan_tpid = {
+       .f = cmd_vlan_tpid_parsed,
+       .data = NULL,
+       .help_str = "set tpid tp_id port_id, set the Outer VLAN Ether type",
+       .tokens = {
+               (void *)&cmd_vlan_tpid_vlan,
+               (void *)&cmd_vlan_tpid_set,
+               (void *)&cmd_vlan_tpid_what,
+               (void *)&cmd_vlan_tpid_tpid,
+               (void *)&cmd_vlan_tpid_portid,
+               NULL,
+       },
+};
+
 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
 struct cmd_rx_vlan_filter_result {
        cmdline_fixed_string_t rx_vlan;
@@ -580,9 +730,9 @@ cmd_rx_vlan_filter_parsed(void *parsed_result,
        struct cmd_rx_vlan_filter_result *res = parsed_result;
 
        if (!strcmp(res->what, "add"))
-               rx_vlan_filter_set(res->port_id, res->vlan_id, 1);
+               rx_vft_set(res->port_id, res->vlan_id, 1);
        else
-               rx_vlan_filter_set(res->port_id, res->vlan_id, 0);
+               rx_vft_set(res->port_id, res->vlan_id, 0);
 }
 
 cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
@@ -626,7 +776,6 @@ cmd_tx_vlan_set_parsed(void *parsed_result,
                       __attribute__((unused)) void *data)
 {
        struct cmd_tx_vlan_set_result *res = parsed_result;
-
        tx_vlan_set(res->port_id, res->vlan_id);
 }
 
@@ -2204,6 +2353,8 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all,
        (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one,
        (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all,
+       (cmdline_parse_inst_t *)&cmd_vlan_offload,
+       (cmdline_parse_inst_t *)&cmd_vlan_tpid,
        (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
        (cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
        (cmdline_parse_inst_t *)&cmd_tx_vlan_set,
index bbf837d..3b7b8f8 100644 (file)
@@ -206,6 +206,7 @@ port_infos_display(portid_t port_id)
 {
        struct rte_port *port;
        struct rte_eth_link link;
+       int vlan_offload;
        static const char *info_border = "*********************";
 
        if (port_id >= nb_ports) {
@@ -227,6 +228,25 @@ port_infos_display(portid_t port_id)
               rte_eth_allmulticast_get(port_id) ? "enabled" : "disabled");
        printf("Maximum number of MAC addresses: %u\n",
               (unsigned int)(port->dev_info.max_mac_addrs));
+
+       vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+       if (vlan_offload >= 0){
+               printf("VLAN offload: \n");
+               if (vlan_offload & ETH_VLAN_STRIP_OFFLOAD)
+                       printf("  strip on \n");
+               else
+                       printf("  strip off \n");
+
+               if (vlan_offload & ETH_VLAN_FILTER_OFFLOAD)
+                       printf("  filter on \n");
+               else
+                       printf("  filter off \n");
+
+               if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)
+                       printf("  qinq(extend) on \n");
+               else
+                       printf("  qinq(extend) off \n");
+       }
 }
 
 static int
@@ -1012,7 +1032,87 @@ set_verbose_level(uint16_t vb_level)
 }
 
 void
-rx_vlan_filter_set(portid_t port_id, uint16_t vlan_id, int on)
+vlan_extend_set(portid_t port_id, int on)
+{
+       int diag;
+       int vlan_offload;
+
+       if (port_id_is_invalid(port_id))
+               return;
+
+       vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+
+       if (on)
+               vlan_offload |= ETH_VLAN_EXTEND_OFFLOAD;
+       else
+               vlan_offload &= ~ETH_VLAN_EXTEND_OFFLOAD;
+
+       diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
+       if (diag < 0)
+               printf("rx_vlan_extend_set(port_pi=%d, on=%d) failed "
+              "diag=%d\n", port_id, on, diag);
+}
+
+void
+rx_vlan_strip_set(portid_t port_id, int on)
+{
+       int diag;
+       int vlan_offload;
+
+       if (port_id_is_invalid(port_id))
+               return;
+
+       vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+
+       if (on)
+               vlan_offload |= ETH_VLAN_STRIP_OFFLOAD;
+       else
+               vlan_offload &= ~ETH_VLAN_STRIP_OFFLOAD;
+
+       diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
+       if (diag < 0)
+               printf("rx_vlan_strip_set(port_pi=%d, on=%d) failed "
+              "diag=%d\n", port_id, on, diag);
+}
+
+void
+rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on)
+{
+       int diag;
+
+       if (port_id_is_invalid(port_id))
+               return;
+
+       diag = rte_eth_dev_set_vlan_strip_on_queue(port_id, queue_id, on);
+       if (diag < 0)
+               printf("rx_vlan_strip_set_on_queue(port_pi=%d, queue_id=%d, on=%d) failed "
+              "diag=%d\n", port_id, queue_id, on, diag);
+}
+
+void
+rx_vlan_filter_set(portid_t port_id, int on)
+{
+       int diag;
+       int vlan_offload;
+
+       if (port_id_is_invalid(port_id))
+               return;
+
+       vlan_offload = rte_eth_dev_get_vlan_offload(port_id);
+
+       if (on)
+               vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
+       else
+               vlan_offload &= ~ETH_VLAN_FILTER_OFFLOAD;
+
+       diag = rte_eth_dev_set_vlan_offload(port_id, vlan_offload);
+       if (diag < 0)
+               printf("rx_vlan_filter_set(port_pi=%d, on=%d) failed "
+              "diag=%d\n", port_id, on, diag);
+}
+
+void
+rx_vft_set(portid_t port_id, uint16_t vlan_id, int on)
 {
        int diag;
 
@@ -1036,7 +1136,23 @@ rx_vlan_all_filter_set(portid_t port_id, int on)
        if (port_id_is_invalid(port_id))
                return;
        for (vlan_id = 0; vlan_id < 4096; vlan_id++)
-               rx_vlan_filter_set(port_id, vlan_id, on);
+               rx_vft_set(port_id, vlan_id, on);
+}
+
+void
+vlan_tpid_set(portid_t port_id, uint16_t tp_id)
+{
+       int diag;
+       if (port_id_is_invalid(port_id))
+               return;
+
+       diag = rte_eth_dev_set_vlan_ether_type(port_id, tp_id);
+       if (diag == 0)
+               return;
+
+       printf("tx_vlan_tpid_set(port_pi=%d, tpid=%d) failed "
+              "diag=%d\n",
+              port_id, tp_id, diag);
 }
 
 void
index 526202a..a478ce6 100644 (file)
@@ -522,8 +522,13 @@ launch_args_parse(int argc, char** argv)
                                rx_mode.hw_strip_crc = 1;
                        if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum"))
                                rx_mode.hw_ip_checksum = 1;
-                       if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan"))
+
+                       if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan")) {
                                rx_mode.hw_vlan_filter = 0;
+                               rx_mode.hw_vlan_strip  = 0;
+                               rx_mode.hw_vlan_extend = 0;
+                       }
+
                        if (!strcmp(lgopts[opt_idx].name, "disable-rss"))
                                rss_hf = 0;
                        if (!strcmp(lgopts[opt_idx].name, "port-topology")) {
index 44614fb..919b395 100644 (file)
@@ -231,6 +231,8 @@ struct rte_eth_rxmode rx_mode = {
        .header_split   = 0, /**< Header Split disabled. */
        .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
        .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
+       .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
+       .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
        .jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
        .hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
 };
index 6a5a6d4..abb31f5 100644 (file)
@@ -380,8 +380,14 @@ void set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt);
 void set_fwd_ports_mask(uint64_t portmask);
 void set_fwd_ports_number(uint16_t nb_pt);
 
-void rx_vlan_filter_set(portid_t port_id, uint16_t vlan_id, int on);
+void rx_vlan_strip_set(portid_t port_id, int on);
+void rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on);
+
+void rx_vlan_filter_set(portid_t port_id, int on);
 void rx_vlan_all_filter_set(portid_t port_id, int on);
+void rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
+void vlan_extend_set(portid_t port_id, int on);
+void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
 void tx_vlan_reset(portid_t port_id);