From 529ba951029e36857c895335226cc9350511be3a Mon Sep 17 00:00:00 2001 From: Helin Zhang Date: Thu, 5 Jun 2014 13:08:50 +0800 Subject: [PATCH] ethdev: set port based vlan To support i40e, new ops has been added to support setting port based vlan insertion. New command 'tx_vlan set pvid port_id vlan_id (on|off)' has been added in testpmd to configure port based vlan insertion. Signed-off-by: Helin Zhang Signed-off-by: Jing Chen Acked-by: Cunming Liang Acked-by: Jijiang Liu Acked-by: Jingjing Wu Acked-by: Heqing Zhu Tested-by: Waterman Cao --- app/test-pmd/cmdline.c | 61 +++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 9 ++++++ app/test-pmd/testpmd.h | 2 +- lib/librte_ether/rte_ethdev.c | 15 +++++++++ lib/librte_ether/rte_ethdev.h | 32 +++++++++++++++++- 5 files changed, 117 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 216752ead1..f64f2dfec8 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -286,6 +286,9 @@ static void cmd_help_long_parsed(void *parsed_result, " Set hardware insertion of VLAN ID in packets sent" " on a port.\n\n" + "tx_vlan set pvid port_id vlan_id (on|off)\n" + " Set port based TX VLAN insertion.\n\n" + "tx_vlan reset (port_id)\n" " Disable hardware insertion of a VLAN header in" " packets sent on a port.\n\n" @@ -2421,6 +2424,63 @@ cmdline_parse_inst_t cmd_tx_vlan_set = { }, }; +/* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */ +struct cmd_tx_vlan_set_pvid_result { + cmdline_fixed_string_t tx_vlan; + cmdline_fixed_string_t set; + cmdline_fixed_string_t pvid; + uint8_t port_id; + uint16_t vlan_id; + cmdline_fixed_string_t mode; +}; + +static void +cmd_tx_vlan_set_pvid_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tx_vlan_set_pvid_result *res = parsed_result; + + if (strcmp(res->mode, "on") == 0) + tx_vlan_pvid_set(res->port_id, res->vlan_id, 1); + else + tx_vlan_pvid_set(res->port_id, res->vlan_id, 0); +} + +cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + tx_vlan, "tx_vlan"); +cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + set, "set"); +cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + pvid, "pvid"); +cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + port_id, UINT8); +cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id = + TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + vlan_id, UINT16); +cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode = + TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result, + mode, "on#off"); + +cmdline_parse_inst_t cmd_tx_vlan_set_pvid = { + .f = cmd_tx_vlan_set_pvid_parsed, + .data = NULL, + .help_str = "tx_vlan set pvid port_id vlan_id (on|off)", + .tokens = { + (void *)&cmd_tx_vlan_set_pvid_tx_vlan, + (void *)&cmd_tx_vlan_set_pvid_set, + (void *)&cmd_tx_vlan_set_pvid_pvid, + (void *)&cmd_tx_vlan_set_pvid_port_id, + (void *)&cmd_tx_vlan_set_pvid_vlan_id, + (void *)&cmd_tx_vlan_set_pvid_mode, + NULL, + }, +}; + /* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */ struct cmd_tx_vlan_reset_result { cmdline_fixed_string_t tx_vlan; @@ -6465,6 +6525,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_rx_vlan_filter, (cmdline_parse_inst_t *)&cmd_tx_vlan_set, (cmdline_parse_inst_t *)&cmd_tx_vlan_reset, + (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid, (cmdline_parse_inst_t *)&cmd_tx_cksum_set, (cmdline_parse_inst_t *)&cmd_link_flow_control_set, (cmdline_parse_inst_t *)&cmd_priority_flow_control_set, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 05071a8334..66fcd745bd 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1582,6 +1582,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) { diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 69afb5b054..aa1942b3e5 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -486,7 +486,7 @@ 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); - +void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on); void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value); diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 3d5d64c269..66eb2660ed 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1360,6 +1360,21 @@ rte_eth_dev_get_vlan_offload(uint8_t port_id) return ret; } +int +rte_eth_dev_set_vlan_pvid(uint8_t port_id, uint16_t pvid, int on) +{ + struct rte_eth_dev *dev; + + if (port_id >= nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + return (-ENODEV); + } + dev = &rte_eth_devices[port_id]; + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_pvid_set, -ENOTSUP); + (*dev->dev_ops->vlan_pvid_set)(dev, pvid, on); + + return 0; +} int rte_eth_dev_fdir_add_signature_filter(uint8_t port_id, diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 6225d39b79..1dd1d39251 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -452,7 +452,6 @@ struct rte_eth_rss_conf { /* Definitions used for receive MAC address */ #define ETH_NUM_RECEIVE_MAC_ADDR 128 /**< Maximum nb. of receive mac addr. */ - /* Definitions used for unicast hash */ #define ETH_VMDQ_NUM_UC_HASH_ARRAY 128 /**< Maximum nb. of UC hash array. */ @@ -586,6 +585,15 @@ struct rte_eth_vmdq_rx_conf { */ struct rte_eth_txmode { enum rte_eth_tx_mq_mode mq_mode; /**< TX multi-queues mode. */ + + /* For i40e specifically */ + uint16_t pvid; + uint8_t hw_vlan_reject_tagged : 1, + /**< If set, reject sending out tagged pkts */ + hw_vlan_reject_untagged : 1, + /**< If set, reject sending out untagged pkts */ + hw_vlan_insert_pvid : 1; + /**< If set, enable port based VLAN insertion */ }; /** @@ -1073,6 +1081,11 @@ typedef void (*vlan_tpid_set_t)(struct rte_eth_dev *dev, typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask); /**< @internal set VLAN offload function by an Ethernet device. */ +typedef int (*vlan_pvid_set_t)(struct rte_eth_dev *dev, + uint16_t vlan_id, + int on); +/**< @internal set port based TX VLAN insertion by an Ethernet device. */ + typedef void (*vlan_strip_queue_set_t)(struct rte_eth_dev *dev, uint16_t rx_queue_id, int on); @@ -1363,6 +1376,7 @@ struct eth_dev_ops { vlan_tpid_set_t vlan_tpid_set; /**< Outer VLAN TPID Setup. */ vlan_strip_queue_set_t vlan_strip_queue_set; /**< VLAN Stripping on queue. */ vlan_offload_set_t vlan_offload_set; /**< Set VLAN Offload. */ + vlan_pvid_set_t vlan_pvid_set; /**< Set port based TX VLAN insertion */ eth_queue_start_t rx_queue_start;/**< Start RX for a queue.*/ eth_queue_stop_t rx_queue_stop;/**< Stop RX for a queue.*/ eth_queue_start_t tx_queue_start;/**< Start TX for a queue.*/ @@ -2130,6 +2144,22 @@ extern int rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask); */ extern int rte_eth_dev_get_vlan_offload(uint8_t port_id); +/** + * Set port based TX VLAN insersion on or off. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param pvid + * Port based TX VLAN identifier togeth with user priority. + * @param on + * Turn on or off the port based TX VLAN insertion. + * + * @return + * - (0) if successful. + * - negative if failed. + */ +extern int rte_eth_dev_set_vlan_pvid(uint8_t port_id, uint16_t pvid, int on); + /** * * Retrieve a burst of input packets from a receive queue of an Ethernet -- 2.20.1