Acked-by: Qiming Yang <qiming.y...@intel.com>
> -----Original Message-----
> From: Wang, Haiyue <haiyue.w...@intel.com>
> Sent: Thursday, February 4, 2021 10:04
> To: dev@dpdk.org
> Cc: Yang, Qiming <qiming.y...@intel.com>; Zhang, Qi Z
> <qi.z.zh...@intel.com>; Wang, Haiyue <haiyue.w...@intel.com>; Creeley,
> Brett <brett.cree...@intel.com>
> Subject: [PATCH v2] net/ice: fix VLAN strip show in double VLAN mode
>
> In double VLAN mode, the VLAN strip is applied on outer, since the VLAN filter
> is outer; in single VLAN mode, the VLAN strip is applied on inner for the VLAN
> filter is inner.
>
> So it needs to adjust the strip setting according to current VLAN mode.
>
> Fixes: 14e7a4b37b4f ("net/ice/base: support configuring device in double VLAN
> mode")
>
> Signed-off-by: Haiyue Wang <haiyue.w...@intel.com>
> ---
> v2: Add the missed fix tag, and update the commit message.
> ---
> drivers/net/ice/ice_ethdev.c | 297 +++++++++++++++--------------------
> 1 file changed, 131 insertions(+), 166 deletions(-)
>
> diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index
> 02a25e8d2a..cb2c0cf449 100644
> --- a/drivers/net/ice/ice_ethdev.c
> +++ b/drivers/net/ice/ice_ethdev.c
> @@ -68,8 +68,6 @@ static struct proto_xtr_ol_flag
> ice_proto_xtr_ol_flag_params[] = {
> .ol_flag = &rte_net_ice_dynflag_proto_xtr_ip_offset_mask }, };
>
> -#define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
> -
> #define ICE_OS_DEFAULT_PKG_NAME "ICE OS Default Package"
> #define ICE_COMMS_PKG_NAME "ICE COMMS
> Package"
> #define ICE_MAX_RES_DESC_NUM 1024
> @@ -1122,127 +1120,6 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi
> *vsi)
> return ret;
> }
>
> -static int
> -ice_vsi_config_qinq_insertion(struct ice_vsi *vsi, bool on) -{
> - struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> - struct ice_vsi_ctx ctxt;
> - uint8_t qinq_flags;
> - int ret = 0;
> -
> - /* Check if it has been already on or off */
> - if (vsi->info.valid_sections &
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) {
> - if (on) {
> - if ((vsi->info.outer_vlan_flags &
> -
> ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST) ==
> -
> ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST)
> - return 0; /* already on */
> - } else {
> - if (!(vsi->info.outer_vlan_flags &
> -
> ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST))
> - return 0; /* already off */
> - }
> - }
> -
> - if (on)
> - qinq_flags =
> ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST;
> - else
> - qinq_flags = 0;
> - /* clear global insertion and use per packet insertion */
> - vsi->info.outer_vlan_flags &=
> ~(ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_INSERT);
> - vsi->info.outer_vlan_flags &=
> ~(ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST);
> - vsi->info.outer_vlan_flags |= qinq_flags;
> - /* use default vlan type 0x8100 */
> - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M);
> - vsi->info.outer_vlan_flags |= ICE_DFLT_OUTER_TAG_TYPE <<
> - ICE_AQ_VSI_OUTER_TAG_TYPE_S;
> - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
> - ctxt.info.valid_sections =
> -
> rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> - ctxt.vsi_num = vsi->vsi_id;
> - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> - if (ret) {
> - PMD_DRV_LOG(INFO,
> - "Update VSI failed to %s qinq stripping",
> - on ? "enable" : "disable");
> - return -EINVAL;
> - }
> -
> - vsi->info.valid_sections |=
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> -
> - return ret;
> -}
> -
> -static int
> -ice_vsi_config_qinq_stripping(struct ice_vsi *vsi, bool on) -{
> - struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> - struct ice_vsi_ctx ctxt;
> - uint8_t qinq_flags;
> - int ret = 0;
> -
> - /* Check if it has been already on or off */
> - if (vsi->info.valid_sections &
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) {
> - if (on) {
> - if ((vsi->info.outer_vlan_flags &
> - ICE_AQ_VSI_OUTER_VLAN_EMODE_M) ==
> - ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW)
> - return 0; /* already on */
> - } else {
> - if ((vsi->info.outer_vlan_flags &
> - ICE_AQ_VSI_OUTER_VLAN_EMODE_M) ==
> - ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH)
> - return 0; /* already off */
> - }
> - }
> -
> - if (on)
> - qinq_flags = ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW;
> - else
> - qinq_flags =
> ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH;
> - vsi->info.outer_vlan_flags &=
> ~(ICE_AQ_VSI_OUTER_VLAN_EMODE_M);
> - vsi->info.outer_vlan_flags |= qinq_flags;
> - /* use default vlan type 0x8100 */
> - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M);
> - vsi->info.outer_vlan_flags |= ICE_DFLT_OUTER_TAG_TYPE <<
> - ICE_AQ_VSI_OUTER_TAG_TYPE_S;
> - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
> - ctxt.info.valid_sections =
> -
> rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> - ctxt.vsi_num = vsi->vsi_id;
> - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> - if (ret) {
> - PMD_DRV_LOG(INFO,
> - "Update VSI failed to %s qinq stripping",
> - on ? "enable" : "disable");
> - return -EINVAL;
> - }
> -
> - vsi->info.valid_sections |=
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> -
> - return ret;
> -}
> -
> -static int
> -ice_vsi_config_double_vlan(struct ice_vsi *vsi, int on) -{
> - int ret;
> -
> - ret = ice_vsi_config_qinq_stripping(vsi, on);
> - if (ret)
> - PMD_DRV_LOG(ERR, "Fail to set qinq stripping - %d", ret);
> -
> - ret = ice_vsi_config_qinq_insertion(vsi, on);
> - if (ret)
> - PMD_DRV_LOG(ERR, "Fail to set qinq insertion - %d", ret);
> -
> - return ret;
> -}
> -
> /* Enable IRQ0 */
> static void
> ice_pf_enable_irq0(struct ice_hw *hw)
> @@ -2220,9 +2097,6 @@ ice_dev_init(struct rte_eth_dev *dev)
>
> vsi = pf->main_vsi;
>
> - /* Disable double vlan by default */
> - ice_vsi_config_double_vlan(vsi, false);
> -
> ret = ice_aq_stop_lldp(hw, true, false, NULL);
> if (ret != ICE_SUCCESS)
> PMD_INIT_LOG(DEBUG, "lldp has already stopped\n"); @@ -
> 4086,49 +3960,147 @@ ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on)
> return 0;
> }
>
> +/* Manage VLAN stripping for the VSI for Rx */
> static int
> -ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool on)
> +ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
> {
> struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> struct ice_vsi_ctx ctxt;
> - uint8_t vlan_flags;
> - int ret = 0;
> + enum ice_status status;
> + int err = 0;
>
> - /* Check if it has been already on or off */
> - if (vsi->info.valid_sections &
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID)) {
> - if (on) {
> - if ((vsi->info.inner_vlan_flags &
> - ICE_AQ_VSI_INNER_VLAN_EMODE_M) ==
> - ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH)
> - return 0; /* already on */
> - } else {
> - if ((vsi->info.inner_vlan_flags &
> - ICE_AQ_VSI_INNER_VLAN_EMODE_M) ==
> - ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING)
> - return 0; /* already off */
> - }
> - }
> + /* do not allow modifying VLAN stripping when a port VLAN is
> configured
> + * on this VSI
> + */
> + if (vsi->info.port_based_inner_vlan)
> + return 0;
>
> - if (on)
> - vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH;
> + memset(&ctxt, 0, sizeof(ctxt));
> +
> + if (ena)
> + /* Strip VLAN tag from Rx packet and put it in the desc */
> + ctxt.info.inner_vlan_flags =
> +
> ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH;
> else
> - vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING;
> - vsi->info.inner_vlan_flags &= ~(ICE_AQ_VSI_INNER_VLAN_EMODE_M);
> - vsi->info.inner_vlan_flags |= vlan_flags;
> - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
> + /* Disable stripping. Leave tag in packet */
> + ctxt.info.inner_vlan_flags =
> +
> ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING;
> +
> + /* Allow all packets untagged/tagged */
> + ctxt.info.inner_vlan_flags |=
> ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL;
> +
> + ctxt.info.valid_sections =
> +rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
> +
> + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> + if (status) {
> + PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan stripping",
> + ena ? "enable" : "disable");
> + err = -EIO;
> + } else {
> + vsi->info.inner_vlan_flags = ctxt.info.inner_vlan_flags;
> + }
> +
> + return err;
> +}
> +
> +static int
> +ice_vsi_ena_inner_stripping(struct ice_vsi *vsi) {
> + return ice_vsi_manage_vlan_stripping(vsi, true); }
> +
> +static int
> +ice_vsi_dis_inner_stripping(struct ice_vsi *vsi) {
> + return ice_vsi_manage_vlan_stripping(vsi, false); }
> +
> +static int ice_vsi_ena_outer_stripping(struct ice_vsi *vsi) {
> + struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> + struct ice_vsi_ctx ctxt;
> + enum ice_status status;
> + int err = 0;
> +
> + /* do not allow modifying VLAN stripping when a port VLAN is
> configured
> + * on this VSI
> + */
> + if (vsi->info.port_based_outer_vlan)
> + return 0;
> +
> + memset(&ctxt, 0, sizeof(ctxt));
> +
> ctxt.info.valid_sections =
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
> - ctxt.vsi_num = vsi->vsi_id;
> - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> - if (ret) {
> - PMD_DRV_LOG(INFO, "Update VSI failed to %s vlan stripping",
> - on ? "enable" : "disable");
> - return -EINVAL;
> + rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> + /* clear current outer VLAN strip settings */
> + ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags &
> + ~(ICE_AQ_VSI_OUTER_VLAN_EMODE_M |
> ICE_AQ_VSI_OUTER_TAG_TYPE_M);
> + ctxt.info.outer_vlan_flags |=
> + (ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH <<
> + ICE_AQ_VSI_OUTER_VLAN_EMODE_S) |
> + (ICE_AQ_VSI_OUTER_TAG_VLAN_8100 <<
> + ICE_AQ_VSI_OUTER_TAG_TYPE_S);
> +
> + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> + if (status) {
> + PMD_DRV_LOG(ERR, "Update VSI failed to enable outer VLAN
> stripping");
> + err = -EIO;
> + } else {
> + vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags;
> }
>
> - vsi->info.valid_sections |=
> - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID);
> + return err;
> +}
> +
> +static int
> +ice_vsi_dis_outer_stripping(struct ice_vsi *vsi) {
> + struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> + struct ice_vsi_ctx ctxt;
> + enum ice_status status;
> + int err = 0;
> +
> + if (vsi->info.port_based_outer_vlan)
> + return 0;
> +
> + memset(&ctxt, 0, sizeof(ctxt));
> +
> + ctxt.info.valid_sections =
> + rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID);
> + /* clear current outer VLAN strip settings */
> + ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags &
> + ~ICE_AQ_VSI_OUTER_VLAN_EMODE_M;
> + ctxt.info.outer_vlan_flags |=
> ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING <<
> + ICE_AQ_VSI_OUTER_VLAN_EMODE_S;
> +
> + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
> + if (status) {
> + PMD_DRV_LOG(ERR, "Update VSI failed to disable outer VLAN
> stripping");
> + err = -EIO;
> + } else {
> + vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags;
> + }
> +
> + return err;
> +}
> +
> +static int
> +ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool ena) {
> + struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
> + int ret;
> +
> + if (ice_is_dvm_ena(hw)) {
> + if (ena)
> + ret = ice_vsi_ena_outer_stripping(vsi);
> + else
> + ret = ice_vsi_dis_outer_stripping(vsi);
> + } else {
> + if (ena)
> + ret = ice_vsi_ena_inner_stripping(vsi);
> + else
> + ret = ice_vsi_dis_inner_stripping(vsi);
> + }
>
> return ret;
> }
> @@ -4155,13 +4127,6 @@ ice_vlan_offload_set(struct rte_eth_dev *dev, int
> mask)
> ice_vsi_config_vlan_stripping(vsi, false);
> }
>
> - if (mask & ETH_VLAN_EXTEND_MASK) {
> - if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
> - ice_vsi_config_double_vlan(vsi, true);
> - else
> - ice_vsi_config_double_vlan(vsi, false);
> - }
> -
> return 0;
> }
>
> --
> 2.30.0