Commit bc42afa9 authored by Brett Creeley's avatar Brett Creeley Committed by Tony Nguyen

ice: Add new VSI VLAN ops

Incoming changes to support 802.1Q and/or 802.1ad VLAN filtering and
offloads require more flexibility when configuring VLANs. The VSI VLAN
interface will allow flexibility for configuring VLANs for all VSI
types. Add new files to separate the VSI VLAN ops and move functions to
make the code more organized.
Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Tested-by: default avatarGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 3e0b5971
...@@ -18,6 +18,8 @@ ice-y := ice_main.o \ ...@@ -18,6 +18,8 @@ ice-y := ice_main.o \
ice_txrx_lib.o \ ice_txrx_lib.o \
ice_txrx.o \ ice_txrx.o \
ice_fltr.o \ ice_fltr.o \
ice_vsi_vlan_ops.o \
ice_vsi_vlan_lib.o \
ice_fdir.o \ ice_fdir.o \
ice_ethtool_fdir.o \ ice_ethtool_fdir.o \
ice_flex_pipe.o \ ice_flex_pipe.o \
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
#include "ice_repr.h" #include "ice_repr.h"
#include "ice_eswitch.h" #include "ice_eswitch.h"
#include "ice_lag.h" #include "ice_lag.h"
#include "ice_vsi_vlan_ops.h"
#define ICE_BAR0 0 #define ICE_BAR0 0
#define ICE_REQ_DESC_MULTIPLE 32 #define ICE_REQ_DESC_MULTIPLE 32
...@@ -368,6 +369,7 @@ struct ice_vsi { ...@@ -368,6 +369,7 @@ struct ice_vsi {
u8 irqs_ready:1; u8 irqs_ready:1;
u8 current_isup:1; /* Sync 'link up' logging */ u8 current_isup:1; /* Sync 'link up' logging */
u8 stat_offsets_loaded:1; u8 stat_offsets_loaded:1;
struct ice_vsi_vlan_ops vlan_ops;
u16 num_vlan; u16 num_vlan;
/* queue information */ /* queue information */
......
...@@ -117,7 +117,7 @@ static int ice_eswitch_setup_env(struct ice_pf *pf) ...@@ -117,7 +117,7 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi; struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi;
bool rule_added = false; bool rule_added = false;
ice_vsi_manage_vlan_stripping(ctrl_vsi, false); ctrl_vsi->vlan_ops.dis_stripping(ctrl_vsi);
ice_remove_vsi_fltr(&pf->hw, uplink_vsi->idx); ice_remove_vsi_fltr(&pf->hw, uplink_vsi->idx);
......
...@@ -1737,62 +1737,6 @@ void ice_update_eth_stats(struct ice_vsi *vsi) ...@@ -1737,62 +1737,6 @@ void ice_update_eth_stats(struct ice_vsi *vsi)
vsi->stat_offsets_loaded = true; vsi->stat_offsets_loaded = true;
} }
/**
* ice_vsi_add_vlan - Add VSI membership for given VLAN
* @vsi: the VSI being configured
* @vid: VLAN ID to be added
* @action: filter action to be performed on match
*/
int
ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action)
{
struct ice_pf *pf = vsi->back;
struct device *dev;
int err = 0;
dev = ice_pf_to_dev(pf);
if (!ice_fltr_add_vlan(vsi, vid, action)) {
vsi->num_vlan++;
} else {
err = -ENODEV;
dev_err(dev, "Failure Adding VLAN %d on VSI %i\n", vid,
vsi->vsi_num);
}
return err;
}
/**
* ice_vsi_kill_vlan - Remove VSI membership for a given VLAN
* @vsi: the VSI being configured
* @vid: VLAN ID to be removed
*
* Returns 0 on success and negative on failure
*/
int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
{
struct ice_pf *pf = vsi->back;
struct device *dev;
int err;
dev = ice_pf_to_dev(pf);
err = ice_fltr_remove_vlan(vsi, vid, ICE_FWD_TO_VSI);
if (!err) {
vsi->num_vlan--;
} else if (err == -ENOENT) {
dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist, error: %d\n",
vid, vsi->vsi_num, err);
err = 0;
} else {
dev_err(dev, "Error removing VLAN %d on vsi %i error: %d\n",
vid, vsi->vsi_num, err);
}
return err;
}
/** /**
* ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
* @vsi: VSI * @vsi: VSI
...@@ -2120,95 +2064,6 @@ void ice_vsi_cfg_msix(struct ice_vsi *vsi) ...@@ -2120,95 +2064,6 @@ void ice_vsi_cfg_msix(struct ice_vsi *vsi)
} }
} }
/**
* ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
* @vsi: the VSI being changed
*/
int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_vsi_ctx *ctxt;
int ret;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
/* Here we are configuring the VSI to let the driver add VLAN tags by
* setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
* insertion happens in the Tx hot path, in ice_tx_map.
*/
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
/* Preserve existing VLAN strip setting */
ctxt->info.vlan_flags |= (vsi->info.vlan_flags &
ICE_AQ_VSI_VLAN_EMOD_M);
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (ret) {
dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN insert failed, err %d aq_err %s\n",
ret, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = ctxt->info.vlan_flags;
out:
kfree(ctxt);
return ret;
}
/**
* ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx
* @vsi: the VSI being changed
* @ena: boolean value indicating if this is a enable or disable request
*/
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_vsi_ctx *ctxt;
int ret;
/* do not allow modifying VLAN stripping when a port VLAN is configured
* on this VSI
*/
if (vsi->info.pvid)
return 0;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
/* Here we are configuring what the VSI should do with the VLAN tag in
* the Rx packet. We can either leave the tag in the packet or put it in
* the Rx descriptor.
*/
if (ena)
/* Strip VLAN tag from Rx packet and put it in the desc */
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
else
/* Disable stripping. Leave tag in packet */
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
/* Allow all packets untagged/tagged */
ctxt->info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (ret) {
dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN strip failed, ena = %d err %d aq_err %s\n",
ena, ret, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = ctxt->info.vlan_flags;
out:
kfree(ctxt);
return ret;
}
/** /**
* ice_vsi_start_all_rx_rings - start/enable all of a VSI's Rx rings * ice_vsi_start_all_rx_rings - start/enable all of a VSI's Rx rings
* @vsi: the VSI whose rings are to be enabled * @vsi: the VSI whose rings are to be enabled
...@@ -2302,61 +2157,6 @@ bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi) ...@@ -2302,61 +2157,6 @@ bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi)
return (vsi->info.sw_flags2 & ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA); return (vsi->info.sw_flags2 & ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA);
} }
/**
* ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI
* @vsi: VSI to enable or disable VLAN pruning on
* @ena: set to true to enable VLAN pruning and false to disable it
*
* returns 0 if VSI is updated, negative otherwise
*/
int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena)
{
struct ice_vsi_ctx *ctxt;
struct ice_pf *pf;
int status;
if (!vsi)
return -EINVAL;
/* Don't enable VLAN pruning if the netdev is currently in promiscuous
* mode. VLAN pruning will be enabled when the interface exits
* promiscuous mode if any VLAN filters are active.
*/
if (vsi->netdev && vsi->netdev->flags & IFF_PROMISC && ena)
return 0;
pf = vsi->back;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
ctxt->info = vsi->info;
if (ena)
ctxt->info.sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
else
ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SW_VALID);
status = ice_update_vsi(&pf->hw, vsi->idx, ctxt, NULL);
if (status) {
netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %d, aq_err = %s\n",
ena ? "En" : "Dis", vsi->idx, vsi->vsi_num,
status, ice_aq_str(pf->hw.adminq.sq_last_status));
goto err_out;
}
vsi->info.sw_flags2 = ctxt->info.sw_flags2;
kfree(ctxt);
return 0;
err_out:
kfree(ctxt);
return -EIO;
}
static void ice_vsi_set_tc_cfg(struct ice_vsi *vsi) static void ice_vsi_set_tc_cfg(struct ice_vsi *vsi)
{ {
if (!test_bit(ICE_FLAG_DCB_ENA, vsi->back->flags)) { if (!test_bit(ICE_FLAG_DCB_ENA, vsi->back->flags)) {
...@@ -2636,6 +2436,8 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi, ...@@ -2636,6 +2436,8 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
if (ret) if (ret)
goto unroll_get_qs; goto unroll_get_qs;
ice_vsi_init_vlan_ops(vsi);
switch (vsi->type) { switch (vsi->type) {
case ICE_VSI_CTRL: case ICE_VSI_CTRL:
case ICE_VSI_SWITCHDEV_CTRL: case ICE_VSI_SWITCHDEV_CTRL:
...@@ -3299,6 +3101,8 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi) ...@@ -3299,6 +3101,8 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
if (vtype == ICE_VSI_VF) if (vtype == ICE_VSI_VF)
vf = &pf->vf[vsi->vf_id]; vf = &pf->vf[vsi->vf_id];
ice_vsi_init_vlan_ops(vsi);
coalesce = kcalloc(vsi->num_q_vectors, coalesce = kcalloc(vsi->num_q_vectors,
sizeof(struct ice_coalesce_stored), GFP_KERNEL); sizeof(struct ice_coalesce_stored), GFP_KERNEL);
if (!coalesce) if (!coalesce)
...@@ -4117,7 +3921,7 @@ int ice_set_link(struct ice_vsi *vsi, bool ena) ...@@ -4117,7 +3921,7 @@ int ice_set_link(struct ice_vsi *vsi, bool ena)
*/ */
int ice_vsi_add_vlan_zero(struct ice_vsi *vsi) int ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
{ {
return ice_vsi_add_vlan(vsi, 0, ICE_FWD_TO_VSI); return vsi->vlan_ops.add_vlan(vsi, 0, ICE_FWD_TO_VSI);
} }
/** /**
......
...@@ -22,15 +22,6 @@ int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi); ...@@ -22,15 +22,6 @@ int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi);
void ice_vsi_cfg_msix(struct ice_vsi *vsi); void ice_vsi_cfg_msix(struct ice_vsi *vsi);
int
ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action);
int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid);
int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi);
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena);
int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi); int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi);
int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi); int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi);
...@@ -45,8 +36,6 @@ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi); ...@@ -45,8 +36,6 @@ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);
bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi); bool ice_vsi_is_vlan_pruning_ena(struct ice_vsi *vsi);
int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena);
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create); void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
int ice_set_link(struct ice_vsi *vsi, bool ena); int ice_set_link(struct ice_vsi *vsi, bool ena);
......
...@@ -396,7 +396,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi) ...@@ -396,7 +396,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
goto out_promisc; goto out_promisc;
} }
err = 0; err = 0;
ice_cfg_vlan_pruning(vsi, false); vsi->vlan_ops.dis_rx_filtering(vsi);
} }
} else { } else {
/* Clear Rx filter to remove traffic from wire */ /* Clear Rx filter to remove traffic from wire */
...@@ -410,7 +410,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi) ...@@ -410,7 +410,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
goto out_promisc; goto out_promisc;
} }
if (vsi->num_vlan > 1) if (vsi->num_vlan > 1)
ice_cfg_vlan_pruning(vsi, true); vsi->vlan_ops.ena_rx_filtering(vsi);
} }
} }
} }
...@@ -3421,7 +3421,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, ...@@ -3421,7 +3421,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto,
/* Enable VLAN pruning when a VLAN other than 0 is added */ /* Enable VLAN pruning when a VLAN other than 0 is added */
if (!ice_vsi_is_vlan_pruning_ena(vsi)) { if (!ice_vsi_is_vlan_pruning_ena(vsi)) {
ret = ice_cfg_vlan_pruning(vsi, true); ret = vsi->vlan_ops.ena_rx_filtering(vsi);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -3429,7 +3429,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto, ...@@ -3429,7 +3429,7 @@ ice_vlan_rx_add_vid(struct net_device *netdev, __always_unused __be16 proto,
/* Add a switch rule for this VLAN ID so its corresponding VLAN tagged /* Add a switch rule for this VLAN ID so its corresponding VLAN tagged
* packets aren't pruned by the device's internal switch on Rx * packets aren't pruned by the device's internal switch on Rx
*/ */
ret = ice_vsi_add_vlan(vsi, vid, ICE_FWD_TO_VSI); ret = vsi->vlan_ops.add_vlan(vsi, vid, ICE_FWD_TO_VSI);
if (!ret) if (!ret)
set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state); set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
...@@ -3456,16 +3456,16 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto, ...@@ -3456,16 +3456,16 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto,
if (!vid) if (!vid)
return 0; return 0;
/* Make sure ice_vsi_kill_vlan is successful before updating VLAN /* Make sure VLAN delete is successful before updating VLAN
* information * information
*/ */
ret = ice_vsi_kill_vlan(vsi, vid); ret = vsi->vlan_ops.del_vlan(vsi, vid);
if (ret) if (ret)
return ret; return ret;
/* Disable pruning when VLAN 0 is the only VLAN rule */ /* Disable pruning when VLAN 0 is the only VLAN rule */
if (vsi->num_vlan == 1 && ice_vsi_is_vlan_pruning_ena(vsi)) if (vsi->num_vlan == 1 && ice_vsi_is_vlan_pruning_ena(vsi))
ret = ice_cfg_vlan_pruning(vsi, false); vsi->vlan_ops.dis_rx_filtering(vsi);
set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state); set_bit(ICE_VSI_VLAN_FLTR_CHANGED, vsi->state);
return ret; return ret;
...@@ -5604,24 +5604,24 @@ ice_set_features(struct net_device *netdev, netdev_features_t features) ...@@ -5604,24 +5604,24 @@ ice_set_features(struct net_device *netdev, netdev_features_t features)
if ((features & NETIF_F_HW_VLAN_CTAG_RX) && if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) !(netdev->features & NETIF_F_HW_VLAN_CTAG_RX))
ret = ice_vsi_manage_vlan_stripping(vsi, true); ret = vsi->vlan_ops.ena_stripping(vsi);
else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) && else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) &&
(netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) (netdev->features & NETIF_F_HW_VLAN_CTAG_RX))
ret = ice_vsi_manage_vlan_stripping(vsi, false); ret = vsi->vlan_ops.dis_stripping(vsi);
if ((features & NETIF_F_HW_VLAN_CTAG_TX) && if ((features & NETIF_F_HW_VLAN_CTAG_TX) &&
!(netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) !(netdev->features & NETIF_F_HW_VLAN_CTAG_TX))
ret = ice_vsi_manage_vlan_insertion(vsi); ret = vsi->vlan_ops.ena_insertion(vsi);
else if (!(features & NETIF_F_HW_VLAN_CTAG_TX) && else if (!(features & NETIF_F_HW_VLAN_CTAG_TX) &&
(netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) (netdev->features & NETIF_F_HW_VLAN_CTAG_TX))
ret = ice_vsi_manage_vlan_insertion(vsi); ret = vsi->vlan_ops.dis_insertion(vsi);
if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) && if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
!(netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) !(netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
ret = ice_cfg_vlan_pruning(vsi, true); ret = vsi->vlan_ops.ena_rx_filtering(vsi);
else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
(netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
ret = ice_cfg_vlan_pruning(vsi, false); ret = vsi->vlan_ops.dis_rx_filtering(vsi);
if ((features & NETIF_F_NTUPLE) && if ((features & NETIF_F_NTUPLE) &&
!(netdev->features & NETIF_F_NTUPLE)) { !(netdev->features & NETIF_F_NTUPLE)) {
...@@ -5657,9 +5657,9 @@ static int ice_vsi_vlan_setup(struct ice_vsi *vsi) ...@@ -5657,9 +5657,9 @@ static int ice_vsi_vlan_setup(struct ice_vsi *vsi)
int ret = 0; int ret = 0;
if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
ret = ice_vsi_manage_vlan_stripping(vsi, true); ret = vsi->vlan_ops.ena_stripping(vsi);
if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_TX) if (vsi->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)
ret = ice_vsi_manage_vlan_insertion(vsi); ret = vsi->vlan_ops.ena_insertion(vsi);
return ret; return ret;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/io-64-nonatomic-lo-hi.h>
#endif #endif
#include <net/udp_tunnel.h>
#define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg))) #define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
#define rd32(a, reg) readl((a)->hw_addr + (reg)) #define rd32(a, reg) readl((a)->hw_addr + (reg))
......
...@@ -33,15 +33,6 @@ struct ice_vsi_ctx { ...@@ -33,15 +33,6 @@ struct ice_vsi_ctx {
struct ice_q_ctx *rdma_q_ctx[ICE_MAX_TRAFFIC_CLASS]; struct ice_q_ctx *rdma_q_ctx[ICE_MAX_TRAFFIC_CLASS];
}; };
enum ice_sw_fwd_act_type {
ICE_FWD_TO_VSI = 0,
ICE_FWD_TO_VSI_LIST, /* Do not use this when adding filter */
ICE_FWD_TO_Q,
ICE_FWD_TO_QGRP,
ICE_DROP_PACKET,
ICE_INVAL_ACT
};
/* Switch recipe ID enum values are specific to hardware */ /* Switch recipe ID enum values are specific to hardware */
enum ice_sw_lkup_type { enum ice_sw_lkup_type {
ICE_SW_LKUP_ETHERTYPE = 0, ICE_SW_LKUP_ETHERTYPE = 0,
......
...@@ -1008,6 +1008,15 @@ struct ice_hw_port_stats { ...@@ -1008,6 +1008,15 @@ struct ice_hw_port_stats {
u64 fd_sb_match; u64 fd_sb_match;
}; };
enum ice_sw_fwd_act_type {
ICE_FWD_TO_VSI = 0,
ICE_FWD_TO_VSI_LIST, /* Do not use this when adding filter */
ICE_FWD_TO_Q,
ICE_FWD_TO_QGRP,
ICE_DROP_PACKET,
ICE_INVAL_ACT
};
struct ice_aq_get_set_rss_lut_params { struct ice_aq_get_set_rss_lut_params {
u16 vsi_handle; /* software VSI handle */ u16 vsi_handle; /* software VSI handle */
u16 lut_size; /* size of the LUT buffer */ u16 lut_size; /* size of the LUT buffer */
......
...@@ -642,55 +642,6 @@ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr) ...@@ -642,55 +642,6 @@ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr)
} }
} }
/**
* ice_vsi_manage_pvid - Enable or disable port VLAN for VSI
* @vsi: the VSI to update
* @pvid_info: VLAN ID and QoS used to set the PVID VSI context field
* @enable: true for enable PVID false for disable
*/
static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 pvid_info, bool enable)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_aqc_vsi_props *info;
struct ice_vsi_ctx *ctxt;
int ret;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
ctxt->info = vsi->info;
info = &ctxt->info;
if (enable) {
info->vlan_flags = ICE_AQ_VSI_VLAN_MODE_UNTAGGED |
ICE_AQ_VSI_PVLAN_INSERT_PVID |
ICE_AQ_VSI_VLAN_EMOD_STR;
info->sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
} else {
info->vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING |
ICE_AQ_VSI_VLAN_MODE_ALL;
info->sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
}
info->pvid = cpu_to_le16(pvid_info);
info->valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
ICE_AQ_VSI_PROP_SW_VALID);
ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (ret) {
dev_info(ice_hw_to_dev(hw), "update VSI for port VLAN failed, err %d aq_err %s\n",
ret, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = info->vlan_flags;
vsi->info.sw_flags2 = info->sw_flags2;
vsi->info.pvid = info->pvid;
out:
kfree(ctxt);
return ret;
}
/** /**
* ice_vf_get_port_info - Get the VF's port info structure * ice_vf_get_port_info - Get the VF's port info structure
* @vf: VF used to get the port info structure for * @vf: VF used to get the port info structure for
...@@ -815,7 +766,7 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf) ...@@ -815,7 +766,7 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf)
int err; int err;
if (vf->port_vlan_info) { if (vf->port_vlan_info) {
err = ice_vsi_manage_pvid(vsi, vf->port_vlan_info, true); err = vsi->vlan_ops.set_port_vlan(vsi, vf->port_vlan_info);
if (err) { if (err) {
dev_err(dev, "failed to configure port VLAN via VSI parameters for VF %u, error %d\n", dev_err(dev, "failed to configure port VLAN via VSI parameters for VF %u, error %d\n",
vf->vf_id, err); vf->vf_id, err);
...@@ -826,7 +777,7 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf) ...@@ -826,7 +777,7 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf)
} }
/* vlan_id will either be 0 or the port VLAN number */ /* vlan_id will either be 0 or the port VLAN number */
err = ice_vsi_add_vlan(vsi, vlan_id, ICE_FWD_TO_VSI); err = vsi->vlan_ops.add_vlan(vsi, vlan_id, ICE_FWD_TO_VSI);
if (err) { if (err) {
dev_err(dev, "failed to add %s VLAN %u filter for VF %u, error %d\n", dev_err(dev, "failed to add %s VLAN %u filter for VF %u, error %d\n",
vf->port_vlan_info ? "port" : "", vlan_id, vf->vf_id, vf->port_vlan_info ? "port" : "", vlan_id, vf->vf_id,
...@@ -837,37 +788,6 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf) ...@@ -837,37 +788,6 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf)
return 0; return 0;
} }
static int ice_cfg_vlan_antispoof(struct ice_vsi *vsi, bool enable)
{
struct ice_vsi_ctx *ctx;
int err;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->info.sec_flags = vsi->info.sec_flags;
ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID);
if (enable)
ctx->info.sec_flags |= ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S;
else
ctx->info.sec_flags &= ~(ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S);
err = ice_update_vsi(&vsi->back->hw, vsi->idx, ctx, NULL);
if (err)
dev_err(ice_pf_to_dev(vsi->back), "Failed to configure Tx VLAN anti-spoof %s for VSI %d, error %d\n",
enable ? "ON" : "OFF", vsi->vsi_num, err);
else
vsi->info.sec_flags = ctx->info.sec_flags;
kfree(ctx);
return err;
}
static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable) static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable)
{ {
struct ice_vsi_ctx *ctx; struct ice_vsi_ctx *ctx;
...@@ -905,7 +825,7 @@ static int ice_vsi_ena_spoofchk(struct ice_vsi *vsi) ...@@ -905,7 +825,7 @@ static int ice_vsi_ena_spoofchk(struct ice_vsi *vsi)
{ {
int err; int err;
err = ice_cfg_vlan_antispoof(vsi, true); err = vsi->vlan_ops.ena_tx_filtering(vsi);
if (err) if (err)
return err; return err;
...@@ -920,7 +840,7 @@ static int ice_vsi_dis_spoofchk(struct ice_vsi *vsi) ...@@ -920,7 +840,7 @@ static int ice_vsi_dis_spoofchk(struct ice_vsi *vsi)
{ {
int err; int err;
err = ice_cfg_vlan_antispoof(vsi, false); err = vsi->vlan_ops.dis_tx_filtering(vsi);
if (err) if (err)
return err; return err;
...@@ -3132,9 +3052,9 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg) ...@@ -3132,9 +3052,9 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
if (vsi->num_vlan || vf->port_vlan_info) { if (vsi->num_vlan || vf->port_vlan_info) {
if (rm_promisc) if (rm_promisc)
ret = ice_cfg_vlan_pruning(vsi, true); ret = vsi->vlan_ops.ena_rx_filtering(vsi);
else else
ret = ice_cfg_vlan_pruning(vsi, false); ret = vsi->vlan_ops.dis_rx_filtering(vsi);
if (ret) { if (ret) {
dev_err(dev, "Failed to configure VLAN pruning in promiscuous mode\n"); dev_err(dev, "Failed to configure VLAN pruning in promiscuous mode\n");
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
...@@ -4331,7 +4251,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v) ...@@ -4331,7 +4251,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
if (!vid) if (!vid)
continue; continue;
status = ice_vsi_add_vlan(vsi, vid, ICE_FWD_TO_VSI); status = vsi->vlan_ops.add_vlan(vsi, vid, ICE_FWD_TO_VSI);
if (status) { if (status) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
goto error_param; goto error_param;
...@@ -4340,7 +4260,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v) ...@@ -4340,7 +4260,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
/* Enable VLAN pruning when non-zero VLAN is added */ /* Enable VLAN pruning when non-zero VLAN is added */
if (!vlan_promisc && vid && if (!vlan_promisc && vid &&
!ice_vsi_is_vlan_pruning_ena(vsi)) { !ice_vsi_is_vlan_pruning_ena(vsi)) {
status = ice_cfg_vlan_pruning(vsi, true); status = vsi->vlan_ops.ena_rx_filtering(vsi);
if (status) { if (status) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
dev_err(dev, "Enable VLAN pruning on VLAN ID: %d failed error-%d\n", dev_err(dev, "Enable VLAN pruning on VLAN ID: %d failed error-%d\n",
...@@ -4382,10 +4302,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v) ...@@ -4382,10 +4302,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
if (!vid) if (!vid)
continue; continue;
/* Make sure ice_vsi_kill_vlan is successful before status = vsi->vlan_ops.del_vlan(vsi, vid);
* updating VLAN information
*/
status = ice_vsi_kill_vlan(vsi, vid);
if (status) { if (status) {
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
goto error_param; goto error_param;
...@@ -4394,7 +4311,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v) ...@@ -4394,7 +4311,7 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
/* Disable VLAN pruning when only VLAN 0 is left */ /* Disable VLAN pruning when only VLAN 0 is left */
if (vsi->num_vlan == 1 && if (vsi->num_vlan == 1 &&
ice_vsi_is_vlan_pruning_ena(vsi)) ice_vsi_is_vlan_pruning_ena(vsi))
ice_cfg_vlan_pruning(vsi, false); status = vsi->vlan_ops.dis_rx_filtering(vsi);
/* Disable Unicast/Multicast VLAN promiscuous mode */ /* Disable Unicast/Multicast VLAN promiscuous mode */
if (vlan_promisc) { if (vlan_promisc) {
...@@ -4463,7 +4380,7 @@ static int ice_vc_ena_vlan_stripping(struct ice_vf *vf) ...@@ -4463,7 +4380,7 @@ static int ice_vc_ena_vlan_stripping(struct ice_vf *vf)
} }
vsi = ice_get_vf_vsi(vf); vsi = ice_get_vf_vsi(vf);
if (ice_vsi_manage_vlan_stripping(vsi, true)) if (vsi->vlan_ops.ena_stripping(vsi))
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
error_param: error_param:
...@@ -4498,7 +4415,7 @@ static int ice_vc_dis_vlan_stripping(struct ice_vf *vf) ...@@ -4498,7 +4415,7 @@ static int ice_vc_dis_vlan_stripping(struct ice_vf *vf)
goto error_param; goto error_param;
} }
if (ice_vsi_manage_vlan_stripping(vsi, false)) if (vsi->vlan_ops.dis_stripping(vsi))
v_ret = VIRTCHNL_STATUS_ERR_PARAM; v_ret = VIRTCHNL_STATUS_ERR_PARAM;
error_param: error_param:
...@@ -4528,9 +4445,9 @@ static int ice_vf_init_vlan_stripping(struct ice_vf *vf) ...@@ -4528,9 +4445,9 @@ static int ice_vf_init_vlan_stripping(struct ice_vf *vf)
return 0; return 0;
if (ice_vf_vlan_offload_ena(vf->driver_caps)) if (ice_vf_vlan_offload_ena(vf->driver_caps))
return ice_vsi_manage_vlan_stripping(vsi, true); return vsi->vlan_ops.ena_stripping(vsi);
else else
return ice_vsi_manage_vlan_stripping(vsi, false); return vsi->vlan_ops.dis_stripping(vsi);
} }
static struct ice_vc_vf_ops ice_vc_vf_dflt_ops = { static struct ice_vc_vf_ops ice_vc_vf_dflt_ops = {
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019-2021, Intel Corporation. */
#include "ice_vsi_vlan_lib.h"
#include "ice_lib.h"
#include "ice_fltr.h"
#include "ice.h"
/**
* ice_vsi_add_vlan - default add VLAN implementation for all VSI types
* @vsi: VSI being configured
* @vid: VLAN ID to be added
* @action: filter action to be performed on match
*/
int
ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action)
{
int err = 0;
if (!ice_fltr_add_vlan(vsi, vid, action)) {
vsi->num_vlan++;
} else {
err = -ENODEV;
dev_err(ice_pf_to_dev(vsi->back), "Failure Adding VLAN %d on VSI %i\n",
vid, vsi->vsi_num);
}
return err;
}
/**
* ice_vsi_del_vlan - default del VLAN implementation for all VSI types
* @vsi: VSI being configured
* @vid: VLAN ID to be removed
*/
int ice_vsi_del_vlan(struct ice_vsi *vsi, u16 vid)
{
struct ice_pf *pf = vsi->back;
struct device *dev;
int err;
dev = ice_pf_to_dev(pf);
err = ice_fltr_remove_vlan(vsi, vid, ICE_FWD_TO_VSI);
if (!err) {
vsi->num_vlan--;
} else if (err == -ENOENT) {
dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist\n",
vid, vsi->vsi_num);
err = 0;
} else {
dev_err(dev, "Error removing VLAN %d on VSI %i error: %d\n",
vid, vsi->vsi_num, err);
}
return err;
}
/**
* ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
* @vsi: the VSI being changed
*/
static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_vsi_ctx *ctxt;
int err;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
/* Here we are configuring the VSI to let the driver add VLAN tags by
* setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
* insertion happens in the Tx hot path, in ice_tx_map.
*/
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
/* Preserve existing VLAN strip setting */
ctxt->info.vlan_flags |= (vsi->info.vlan_flags &
ICE_AQ_VSI_VLAN_EMOD_M);
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
err = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (err) {
dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN insert failed, err %d aq_err %s\n",
err, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = ctxt->info.vlan_flags;
out:
kfree(ctxt);
return err;
}
/**
* ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx
* @vsi: the VSI being changed
* @ena: boolean value indicating if this is a enable or disable request
*/
static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_vsi_ctx *ctxt;
int err;
/* do not allow modifying VLAN stripping when a port VLAN is configured
* on this VSI
*/
if (vsi->info.pvid)
return 0;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
/* Here we are configuring what the VSI should do with the VLAN tag in
* the Rx packet. We can either leave the tag in the packet or put it in
* the Rx descriptor.
*/
if (ena)
/* Strip VLAN tag from Rx packet and put it in the desc */
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
else
/* Disable stripping. Leave tag in packet */
ctxt->info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
/* Allow all packets untagged/tagged */
ctxt->info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
err = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (err) {
dev_err(ice_pf_to_dev(vsi->back), "update VSI for VLAN strip failed, ena = %d err %d aq_err %s\n",
ena, err, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = ctxt->info.vlan_flags;
out:
kfree(ctxt);
return err;
}
int ice_vsi_ena_stripping(struct ice_vsi *vsi)
{
return ice_vsi_manage_vlan_stripping(vsi, true);
}
int ice_vsi_dis_stripping(struct ice_vsi *vsi)
{
return ice_vsi_manage_vlan_stripping(vsi, false);
}
int ice_vsi_ena_insertion(struct ice_vsi *vsi)
{
return ice_vsi_manage_vlan_insertion(vsi);
}
int ice_vsi_dis_insertion(struct ice_vsi *vsi)
{
return ice_vsi_manage_vlan_insertion(vsi);
}
/**
* ice_vsi_manage_pvid - Enable or disable port VLAN for VSI
* @vsi: the VSI to update
* @pvid_info: VLAN ID and QoS used to set the PVID VSI context field
* @enable: true for enable PVID false for disable
*/
static int ice_vsi_manage_pvid(struct ice_vsi *vsi, u16 pvid_info, bool enable)
{
struct ice_hw *hw = &vsi->back->hw;
struct ice_aqc_vsi_props *info;
struct ice_vsi_ctx *ctxt;
int ret;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
ctxt->info = vsi->info;
info = &ctxt->info;
if (enable) {
info->vlan_flags = ICE_AQ_VSI_VLAN_MODE_UNTAGGED |
ICE_AQ_VSI_PVLAN_INSERT_PVID |
ICE_AQ_VSI_VLAN_EMOD_STR;
info->sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
} else {
info->vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING |
ICE_AQ_VSI_VLAN_MODE_ALL;
info->sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
}
info->pvid = cpu_to_le16(pvid_info);
info->valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID |
ICE_AQ_VSI_PROP_SW_VALID);
ret = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
if (ret) {
dev_info(ice_hw_to_dev(hw), "update VSI for port VLAN failed, err %d aq_err %s\n",
ret, ice_aq_str(hw->adminq.sq_last_status));
goto out;
}
vsi->info.vlan_flags = info->vlan_flags;
vsi->info.sw_flags2 = info->sw_flags2;
vsi->info.pvid = info->pvid;
out:
kfree(ctxt);
return ret;
}
int ice_vsi_set_port_vlan(struct ice_vsi *vsi, u16 pvid_info)
{
return ice_vsi_manage_pvid(vsi, pvid_info, true);
}
/**
* ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI
* @vsi: VSI to enable or disable VLAN pruning on
* @ena: set to true to enable VLAN pruning and false to disable it
*
* returns 0 if VSI is updated, negative otherwise
*/
static int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena)
{
struct ice_vsi_ctx *ctxt;
struct ice_pf *pf;
int status;
if (!vsi)
return -EINVAL;
/* Don't enable VLAN pruning if the netdev is currently in promiscuous
* mode. VLAN pruning will be enabled when the interface exits
* promiscuous mode if any VLAN filters are active.
*/
if (vsi->netdev && vsi->netdev->flags & IFF_PROMISC && ena)
return 0;
pf = vsi->back;
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt)
return -ENOMEM;
ctxt->info = vsi->info;
if (ena)
ctxt->info.sw_flags2 |= ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
else
ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SW_VALID);
status = ice_update_vsi(&pf->hw, vsi->idx, ctxt, NULL);
if (status) {
netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %d, aq_err = %s\n",
ena ? "En" : "Dis", vsi->idx, vsi->vsi_num, status,
ice_aq_str(pf->hw.adminq.sq_last_status));
goto err_out;
}
vsi->info.sw_flags2 = ctxt->info.sw_flags2;
kfree(ctxt);
return 0;
err_out:
kfree(ctxt);
return status;
}
int ice_vsi_ena_rx_vlan_filtering(struct ice_vsi *vsi)
{
return ice_cfg_vlan_pruning(vsi, true);
}
int ice_vsi_dis_rx_vlan_filtering(struct ice_vsi *vsi)
{
return ice_cfg_vlan_pruning(vsi, false);
}
static int ice_cfg_vlan_antispoof(struct ice_vsi *vsi, bool enable)
{
struct ice_vsi_ctx *ctx;
int err;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->info.sec_flags = vsi->info.sec_flags;
ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_SECURITY_VALID);
if (enable)
ctx->info.sec_flags |= ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S;
else
ctx->info.sec_flags &= ~(ICE_AQ_VSI_SEC_TX_VLAN_PRUNE_ENA <<
ICE_AQ_VSI_SEC_TX_PRUNE_ENA_S);
err = ice_update_vsi(&vsi->back->hw, vsi->idx, ctx, NULL);
if (err)
dev_err(ice_pf_to_dev(vsi->back), "Failed to configure Tx VLAN anti-spoof %s for VSI %d, error %d\n",
enable ? "ON" : "OFF", vsi->vsi_num, err);
else
vsi->info.sec_flags = ctx->info.sec_flags;
kfree(ctx);
return err;
}
int ice_vsi_ena_tx_vlan_filtering(struct ice_vsi *vsi)
{
return ice_cfg_vlan_antispoof(vsi, true);
}
int ice_vsi_dis_tx_vlan_filtering(struct ice_vsi *vsi)
{
return ice_cfg_vlan_antispoof(vsi, false);
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2019-2021, Intel Corporation. */
#ifndef _ICE_VSI_VLAN_LIB_H_
#define _ICE_VSI_VLAN_LIB_H_
#include <linux/types.h>
#include "ice_type.h"
struct ice_vsi;
int
ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action);
int ice_vsi_del_vlan(struct ice_vsi *vsi, u16 vid);
int ice_vsi_ena_stripping(struct ice_vsi *vsi);
int ice_vsi_dis_stripping(struct ice_vsi *vsi);
int ice_vsi_ena_insertion(struct ice_vsi *vsi);
int ice_vsi_dis_insertion(struct ice_vsi *vsi);
int ice_vsi_set_port_vlan(struct ice_vsi *vsi, u16 pvid_info);
int ice_vsi_ena_rx_vlan_filtering(struct ice_vsi *vsi);
int ice_vsi_dis_rx_vlan_filtering(struct ice_vsi *vsi);
int ice_vsi_ena_tx_vlan_filtering(struct ice_vsi *vsi);
int ice_vsi_dis_tx_vlan_filtering(struct ice_vsi *vsi);
#endif /* _ICE_VSI_VLAN_LIB_H_ */
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019-2021, Intel Corporation. */
#include "ice_vsi_vlan_ops.h"
#include "ice.h"
void ice_vsi_init_vlan_ops(struct ice_vsi *vsi)
{
vsi->vlan_ops.add_vlan = ice_vsi_add_vlan;
vsi->vlan_ops.del_vlan = ice_vsi_del_vlan;
vsi->vlan_ops.ena_stripping = ice_vsi_ena_stripping;
vsi->vlan_ops.dis_stripping = ice_vsi_dis_stripping;
vsi->vlan_ops.ena_insertion = ice_vsi_ena_insertion;
vsi->vlan_ops.dis_insertion = ice_vsi_dis_insertion;
vsi->vlan_ops.ena_rx_filtering = ice_vsi_ena_rx_vlan_filtering;
vsi->vlan_ops.dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering;
vsi->vlan_ops.ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering;
vsi->vlan_ops.dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering;
vsi->vlan_ops.set_port_vlan = ice_vsi_set_port_vlan;
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2019-2021, Intel Corporation. */
#ifndef _ICE_VSI_VLAN_OPS_H_
#define _ICE_VSI_VLAN_OPS_H_
#include "ice_type.h"
#include "ice_vsi_vlan_lib.h"
struct ice_vsi;
struct ice_vsi_vlan_ops {
int (*add_vlan)(struct ice_vsi *vsi, u16 vid, enum ice_sw_fwd_act_type action);
int (*del_vlan)(struct ice_vsi *vsi, u16 vid);
int (*ena_stripping)(struct ice_vsi *vsi);
int (*dis_stripping)(struct ice_vsi *vsi);
int (*ena_insertion)(struct ice_vsi *vsi);
int (*dis_insertion)(struct ice_vsi *vsi);
int (*ena_rx_filtering)(struct ice_vsi *vsi);
int (*dis_rx_filtering)(struct ice_vsi *vsi);
int (*ena_tx_filtering)(struct ice_vsi *vsi);
int (*dis_tx_filtering)(struct ice_vsi *vsi);
int (*set_port_vlan)(struct ice_vsi *vsi, u16 pvid_info);
};
void ice_vsi_init_vlan_ops(struct ice_vsi *vsi);
#endif /* _ICE_VSI_VLAN_OPS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment