Commit 1fe8a3b6 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
ice: various virtualization cleanups

Jacob Keller says:

This series contains a variety of refactors and cleanups in the VF code for
the ice driver. Its primary focus is cleanup and simplification of the VF
operations and addition of a few new operations that will be required by
Scalable IOV, as well as some other refactors needed for the handling of VF
subfunctions.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: remove unnecessary virtchnl_ether_addr struct use
  ice: introduce .irq_close VF operation
  ice: introduce clear_reset_state operation
  ice: convert vf_ops .vsi_rebuild to .create_vsi
  ice: introduce ice_vf_init_host_cfg function
  ice: add a function to initialize vf entry
  ice: Pull common tasks into ice_vf_post_vsi_rebuild
  ice: move ice_vf_vsi_release into ice_vf_lib.c
  ice: move vsi_type assignment from ice_vsi_alloc to ice_vsi_cfg
  ice: refactor VSI setup to use parameter structure
  ice: drop unnecessary VF parameter from several VSI functions
  ice: fix function comment referring to ice_vsi_alloc
  ice: Add more usage of existing function ice_get_vf_vsi(vf)
====================

Link: https://lore.kernel.org/r/20230206214813.20107-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents cb6b2e11 e0645311
......@@ -71,17 +71,17 @@ void ice_eswitch_replay_vf_mac_rule(struct ice_vf *vf)
if (!ice_is_switchdev_running(vf->pf))
return;
if (is_valid_ether_addr(vf->hw_lan_addr.addr)) {
if (is_valid_ether_addr(vf->hw_lan_addr)) {
err = ice_eswitch_add_vf_mac_rule(vf->pf, vf,
vf->hw_lan_addr.addr);
vf->hw_lan_addr);
if (err) {
dev_err(ice_pf_to_dev(vf->pf), "Failed to add MAC %pM for VF %d\n, error %d\n",
vf->hw_lan_addr.addr, vf->vf_id, err);
vf->hw_lan_addr, vf->vf_id, err);
return;
}
vf->num_mac++;
ether_addr_copy(vf->dev_lan_addr.addr, vf->hw_lan_addr.addr);
ether_addr_copy(vf->dev_lan_addr, vf->hw_lan_addr);
}
}
......@@ -237,7 +237,7 @@ ice_eswitch_release_reprs(struct ice_pf *pf, struct ice_vsi *ctrl_vsi)
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr,
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
netif_napi_del(&vf->repr->q_vector->napi);
......@@ -265,14 +265,14 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
GFP_KERNEL);
if (!vf->repr->dst) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr.addr,
vf->hw_lan_addr,
ICE_FWD_TO_VSI);
goto err;
}
if (ice_vsi_update_security(vsi, ice_vsi_ctx_clear_antispoof)) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr.addr,
vf->hw_lan_addr,
ICE_FWD_TO_VSI);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
......@@ -281,7 +281,7 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
if (ice_vsi_add_vlan_zero(vsi)) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr.addr,
vf->hw_lan_addr,
ICE_FWD_TO_VSI);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
......@@ -338,7 +338,7 @@ void ice_eswitch_update_repr(struct ice_vsi *vsi)
ret = ice_vsi_update_security(vsi, ice_vsi_ctx_clear_antispoof);
if (ret) {
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr.addr, ICE_FWD_TO_VSI);
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr, ICE_FWD_TO_VSI);
dev_err(ice_pf_to_dev(pf), "Failed to update VF %d port representor",
vsi->vf->vf_id);
}
......@@ -425,7 +425,13 @@ static void ice_eswitch_release_env(struct ice_pf *pf)
static struct ice_vsi *
ice_eswitch_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
{
return ice_vsi_setup(pf, pi, ICE_VSI_SWITCHDEV_CTRL, NULL, NULL);
struct ice_vsi_cfg_params params = {};
params.type = ICE_VSI_SWITCHDEV_CTRL;
params.pi = pi;
params.flags = ICE_VSI_FLAG_INIT;
return ice_vsi_setup(pf, &params);
}
/**
......
This diff is collapsed.
......@@ -7,6 +7,47 @@
#include "ice.h"
#include "ice_vlan.h"
/* Flags used for VSI configuration and rebuild */
#define ICE_VSI_FLAG_INIT BIT(0)
#define ICE_VSI_FLAG_NO_INIT 0
/**
* struct ice_vsi_cfg_params - VSI configuration parameters
* @pi: pointer to the port_info instance for the VSI
* @ch: pointer to the channel structure for the VSI, may be NULL
* @vf: pointer to the VF associated with this VSI, may be NULL
* @type: the type of VSI to configure
* @flags: VSI flags used for rebuild and configuration
*
* Parameter structure used when configuring a new VSI.
*/
struct ice_vsi_cfg_params {
struct ice_port_info *pi;
struct ice_channel *ch;
struct ice_vf *vf;
enum ice_vsi_type type;
u32 flags;
};
/**
* ice_vsi_to_params - Get parameters for an existing VSI
* @vsi: the VSI to get parameters for
*
* Fill a parameter structure for reconfiguring a VSI with its current
* parameters, such as during a rebuild operation.
*/
static inline struct ice_vsi_cfg_params ice_vsi_to_params(struct ice_vsi *vsi)
{
struct ice_vsi_cfg_params params = {};
params.pi = vsi->port_info;
params.ch = vsi->ch;
params.vf = vsi->vf;
params.type = vsi->type;
return params;
}
const char *ice_vsi_type_str(enum ice_vsi_type vsi_type);
bool ice_pf_state_is_nominal(struct ice_pf *pf);
......@@ -50,9 +91,7 @@ int ice_vsi_cfg_rss_lut_key(struct ice_vsi *vsi);
void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc);
struct ice_vsi *
ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
enum ice_vsi_type vsi_type, struct ice_vf *vf,
struct ice_channel *ch);
ice_vsi_setup(struct ice_pf *pf, struct ice_vsi_cfg_params *params);
void ice_napi_del(struct ice_vsi *vsi);
......@@ -70,11 +109,8 @@ int ice_free_res(struct ice_res_tracker *res, u16 index, u16 id);
int
ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id);
#define ICE_VSI_FLAG_INIT BIT(0)
#define ICE_VSI_FLAG_NO_INIT 0
int ice_vsi_rebuild(struct ice_vsi *vsi, int init_vsi);
int ice_vsi_cfg(struct ice_vsi *vsi, struct ice_vf *vf,
struct ice_channel *ch, int init_vsi);
int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags);
int ice_vsi_cfg(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params);
bool ice_is_reset_in_progress(unsigned long *state);
int ice_wait_for_reset(struct ice_pf *pf, unsigned long timeout);
......
......@@ -537,7 +537,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
/* Disable VFs until reset is completed */
mutex_lock(&pf->vfs.table_lock);
ice_for_each_vf(pf, bkt, vf)
ice_set_vf_state_qs_dis(vf);
ice_set_vf_state_dis(vf);
mutex_unlock(&pf->vfs.table_lock);
if (ice_is_eswitch_mode_switchdev(pf)) {
......@@ -3447,14 +3447,27 @@ void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)
static struct ice_vsi *
ice_pf_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
{
return ice_vsi_setup(pf, pi, ICE_VSI_PF, NULL, NULL);
struct ice_vsi_cfg_params params = {};
params.type = ICE_VSI_PF;
params.pi = pi;
params.flags = ICE_VSI_FLAG_INIT;
return ice_vsi_setup(pf, &params);
}
static struct ice_vsi *
ice_chnl_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
struct ice_channel *ch)
{
return ice_vsi_setup(pf, pi, ICE_VSI_CHNL, NULL, ch);
struct ice_vsi_cfg_params params = {};
params.type = ICE_VSI_CHNL;
params.pi = pi;
params.ch = ch;
params.flags = ICE_VSI_FLAG_INIT;
return ice_vsi_setup(pf, &params);
}
/**
......@@ -3468,7 +3481,13 @@ ice_chnl_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
static struct ice_vsi *
ice_ctrl_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
{
return ice_vsi_setup(pf, pi, ICE_VSI_CTRL, NULL, NULL);
struct ice_vsi_cfg_params params = {};
params.type = ICE_VSI_CTRL;
params.pi = pi;
params.flags = ICE_VSI_FLAG_INIT;
return ice_vsi_setup(pf, &params);
}
/**
......@@ -3482,7 +3501,13 @@ ice_ctrl_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
struct ice_vsi *
ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
{
return ice_vsi_setup(pf, pi, ICE_VSI_LB, NULL, NULL);
struct ice_vsi_cfg_params params = {};
params.type = ICE_VSI_LB;
params.pi = pi;
params.flags = ICE_VSI_FLAG_INIT;
return ice_vsi_setup(pf, &params);
}
/**
......@@ -5002,6 +5027,7 @@ static void ice_deinit(struct ice_pf *pf)
*/
int ice_load(struct ice_pf *pf)
{
struct ice_vsi_cfg_params params = {};
struct ice_vsi *vsi;
int err;
......@@ -5014,7 +5040,11 @@ int ice_load(struct ice_pf *pf)
return err;
vsi = ice_get_main_vsi(pf);
err = ice_vsi_cfg(vsi, NULL, NULL, ICE_VSI_FLAG_INIT);
params = ice_vsi_to_params(vsi);
params.flags = ICE_VSI_FLAG_INIT;
err = ice_vsi_cfg(vsi, &params);
if (err)
goto err_vsi_cfg;
......
......@@ -40,21 +40,6 @@ static void ice_free_vf_entries(struct ice_pf *pf)
}
}
/**
* ice_vf_vsi_release - invalidate the VF's VSI after freeing it
* @vf: invalidate this VF's VSI after freeing it
*/
static void ice_vf_vsi_release(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi))
return;
ice_vsi_release(vsi);
ice_vf_invalidate_vsi(vf);
}
/**
* ice_free_vf_res - Free a VF's resources
* @vf: pointer to the VF info
......@@ -248,11 +233,16 @@ void ice_free_vfs(struct ice_pf *pf)
*/
static struct ice_vsi *ice_vf_vsi_setup(struct ice_vf *vf)
{
struct ice_port_info *pi = ice_vf_get_port_info(vf);
struct ice_vsi_cfg_params params = {};
struct ice_pf *pf = vf->pf;
struct ice_vsi *vsi;
vsi = ice_vsi_setup(pf, pi, ICE_VSI_VF, vf, NULL);
params.type = ICE_VSI_VF;
params.pi = ice_vf_get_port_info(vf);
params.vf = vf;
params.flags = ICE_VSI_FLAG_INIT;
vsi = ice_vsi_setup(pf, &params);
if (!vsi) {
dev_err(ice_pf_to_dev(pf), "Failed to create VF VSI\n");
......@@ -583,51 +573,19 @@ static int ice_set_per_vf_res(struct ice_pf *pf, u16 num_vfs)
*/
static int ice_init_vf_vsi_res(struct ice_vf *vf)
{
struct ice_vsi_vlan_ops *vlan_ops;
struct ice_pf *pf = vf->pf;
u8 broadcast[ETH_ALEN];
struct ice_vsi *vsi;
struct device *dev;
int err;
vf->first_vector_idx = ice_calc_vf_first_vector_idx(pf, vf);
dev = ice_pf_to_dev(pf);
vsi = ice_vf_vsi_setup(vf);
if (!vsi)
return -ENOMEM;
err = ice_vsi_add_vlan_zero(vsi);
if (err) {
dev_warn(dev, "Failed to add VLAN 0 filter for VF %d\n",
vf->vf_id);
goto release_vsi;
}
vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
err = vlan_ops->ena_rx_filtering(vsi);
if (err) {
dev_warn(dev, "Failed to enable Rx VLAN filtering for VF %d\n",
vf->vf_id);
goto release_vsi;
}
eth_broadcast_addr(broadcast);
err = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
if (err) {
dev_err(dev, "Failed to add broadcast MAC filter for VF %d, error %d\n",
vf->vf_id, err);
goto release_vsi;
}
err = ice_vsi_apply_spoofchk(vsi, vf->spoofchk);
if (err) {
dev_warn(dev, "Failed to initialize spoofchk setting for VF %d\n",
vf->vf_id);
err = ice_vf_init_host_cfg(vf, vsi);
if (err)
goto release_vsi;
}
vf->num_mac = 1;
return 0;
......@@ -696,6 +654,21 @@ static void ice_sriov_free_vf(struct ice_vf *vf)
kfree_rcu(vf, rcu);
}
/**
* ice_sriov_clear_reset_state - clears VF Reset status register
* @vf: the vf to configure
*/
static void ice_sriov_clear_reset_state(struct ice_vf *vf)
{
struct ice_hw *hw = &vf->pf->hw;
/* Clear the reset status register so that VF immediately sees that
* the device is resetting, even if hardware hasn't yet gotten around
* to clearing VFGEN_RSTAT for us.
*/
wr32(hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_INPROGRESS);
}
/**
* ice_sriov_clear_mbx_register - clears SRIOV VF's mailbox registers
* @vf: the vf to configure
......@@ -799,23 +772,19 @@ static void ice_sriov_clear_reset_trigger(struct ice_vf *vf)
}
/**
* ice_sriov_vsi_rebuild - release and rebuild VF's VSI
* @vf: VF to release and setup the VSI for
* ice_sriov_create_vsi - Create a new VSI for a VF
* @vf: VF to create the VSI for
*
* This is only called when a single VF is being reset (i.e. VFR, VFLR, host VF
* configuration change, etc.).
* This is called by ice_vf_recreate_vsi to create the new VSI after the old
* VSI has been released.
*/
static int ice_sriov_vsi_rebuild(struct ice_vf *vf)
static int ice_sriov_create_vsi(struct ice_vf *vf)
{
struct ice_pf *pf = vf->pf;
struct ice_vsi *vsi;
ice_vf_vsi_release(vf);
if (!ice_vf_vsi_setup(vf)) {
dev_err(ice_pf_to_dev(pf),
"Failed to release and setup the VF%u's VSI\n",
vf->vf_id);
vsi = ice_vf_vsi_setup(vf);
if (!vsi)
return -ENOMEM;
}
return 0;
}
......@@ -826,8 +795,6 @@ static int ice_sriov_vsi_rebuild(struct ice_vf *vf)
*/
static void ice_sriov_post_vsi_rebuild(struct ice_vf *vf)
{
ice_vf_rebuild_host_cfg(vf);
ice_vf_set_initialized(vf);
ice_ena_vf_mappings(vf);
wr32(&vf->pf->hw, VFGEN_RSTAT(vf->vf_id), VIRTCHNL_VFR_VFACTIVE);
}
......@@ -835,11 +802,13 @@ static void ice_sriov_post_vsi_rebuild(struct ice_vf *vf)
static const struct ice_vf_ops ice_sriov_vf_ops = {
.reset_type = ICE_VF_RESET,
.free = ice_sriov_free_vf,
.clear_reset_state = ice_sriov_clear_reset_state,
.clear_mbx_register = ice_sriov_clear_mbx_register,
.trigger_reset_register = ice_sriov_trigger_reset_register,
.poll_reset_status = ice_sriov_poll_reset_status,
.clear_reset_trigger = ice_sriov_clear_reset_trigger,
.vsi_rebuild = ice_sriov_vsi_rebuild,
.irq_close = NULL,
.create_vsi = ice_sriov_create_vsi,
.post_vsi_rebuild = ice_sriov_post_vsi_rebuild,
};
......@@ -879,21 +848,9 @@ static int ice_create_vf_entries(struct ice_pf *pf, u16 num_vfs)
/* set sriov vf ops for VFs created during SRIOV flow */
vf->vf_ops = &ice_sriov_vf_ops;
vf->vf_sw_id = pf->first_sw;
/* assign default capabilities */
vf->spoofchk = true;
vf->num_vf_qs = pf->vfs.num_qps_per;
ice_vc_set_default_allowlist(vf);
/* ctrl_vsi_idx will be set to a valid value only when VF
* creates its first fdir rule.
*/
ice_vf_ctrl_invalidate_vsi(vf);
ice_vf_fdir_init(vf);
ice_virtchnl_set_dflt_ops(vf);
ice_initialize_vf_entry(vf);
mutex_init(&vf->cfg_lock);
vf->vf_sw_id = pf->first_sw;
hash_add_rcu(vfs->table, &vf->entry, vf_id);
}
......@@ -1285,7 +1242,7 @@ ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi)
goto out_put_vf;
ivi->vf = vf_id;
ether_addr_copy(ivi->mac, vf->hw_lan_addr.addr);
ether_addr_copy(ivi->mac, vf->hw_lan_addr);
/* VF configuration for VLAN and applicable QoS */
ivi->vlan = ice_vf_get_port_vlan_id(vf);
......@@ -1333,8 +1290,8 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
return -EINVAL;
/* nothing left to do, unicast MAC already set */
if (ether_addr_equal(vf->dev_lan_addr.addr, mac) &&
ether_addr_equal(vf->hw_lan_addr.addr, mac)) {
if (ether_addr_equal(vf->dev_lan_addr, mac) &&
ether_addr_equal(vf->hw_lan_addr, mac)) {
ret = 0;
goto out_put_vf;
}
......@@ -1348,8 +1305,8 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
/* VF is notified of its new MAC via the PF's response to the
* VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset
*/
ether_addr_copy(vf->dev_lan_addr.addr, mac);
ether_addr_copy(vf->hw_lan_addr.addr, mac);
ether_addr_copy(vf->dev_lan_addr, mac);
ether_addr_copy(vf->hw_lan_addr, mac);
if (is_zero_ether_addr(mac)) {
/* VF will send VIRTCHNL_OP_ADD_ETH_ADDR message with its MAC */
vf->pf_set_mac = false;
......@@ -1750,7 +1707,7 @@ void ice_print_vf_rx_mdd_event(struct ice_vf *vf)
dev_info(dev, "%d Rx Malicious Driver Detection events detected on PF %d VF %d MAC %pM. mdd-auto-reset-vfs=%s\n",
vf->mdd_rx_events.count, pf->hw.pf_id, vf->vf_id,
vf->dev_lan_addr.addr,
vf->dev_lan_addr,
test_bit(ICE_FLAG_MDD_AUTO_RESET_VF, pf->flags)
? "on" : "off");
}
......@@ -1794,7 +1751,7 @@ void ice_print_vfs_mdd_events(struct ice_pf *pf)
dev_info(dev, "%d Tx Malicious Driver Detection events detected on PF %d VF %d MAC %pM.\n",
vf->mdd_tx_events.count, hw->pf_id, vf->vf_id,
vf->dev_lan_addr.addr);
vf->dev_lan_addr);
}
}
mutex_unlock(&pf->vfs.table_lock);
......@@ -1884,7 +1841,7 @@ ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event,
if (pf_vsi)
dev_warn(dev, "VF MAC %pM on PF MAC %pM is generating asynchronous messages and may be overflowing the PF message queue. Please see the Adapter User Guide for more information\n",
&vf->dev_lan_addr.addr[0],
&vf->dev_lan_addr[0],
pf_vsi->netdev->dev_addr);
}
}
......
......@@ -237,16 +237,49 @@ static void ice_vf_clear_counters(struct ice_vf *vf)
*/
static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf)
{
/* Close any IRQ mapping now */
if (vf->vf_ops->irq_close)
vf->vf_ops->irq_close(vf);
ice_vf_clear_counters(vf);
vf->vf_ops->clear_reset_trigger(vf);
}
/**
* ice_vf_recreate_vsi - Release and re-create the VF's VSI
* @vf: VF to recreate the VSI for
*
* This is only called when a single VF is being reset (i.e. VVF, VFLR, host
* VF configuration change, etc)
*
* It releases and then re-creates a new VSI.
*/
static int ice_vf_recreate_vsi(struct ice_vf *vf)
{
struct ice_pf *pf = vf->pf;
int err;
ice_vf_vsi_release(vf);
err = vf->vf_ops->create_vsi(vf);
if (err) {
dev_err(ice_pf_to_dev(pf),
"Failed to recreate the VF%u's VSI, error %d\n",
vf->vf_id, err);
return err;
}
return 0;
}
/**
* ice_vf_rebuild_vsi - rebuild the VF's VSI
* @vf: VF to rebuild the VSI for
*
* This is only called when all VF(s) are being reset (i.e. PCIe Reset on the
* host, PFR, CORER, etc.).
*
* It reprograms the VSI configuration back into hardware.
*/
static int ice_vf_rebuild_vsi(struct ice_vf *vf)
{
......@@ -270,6 +303,21 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf)
return 0;
}
/**
* ice_vf_post_vsi_rebuild - Reset tasks that occur after VSI rebuild
* @vf: the VF being reset
*
* Perform reset tasks which must occur after the VSI has been re-created or
* rebuilt during a VF reset.
*/
static void ice_vf_post_vsi_rebuild(struct ice_vf *vf)
{
ice_vf_rebuild_host_cfg(vf);
ice_vf_set_initialized(vf);
vf->vf_ops->post_vsi_rebuild(vf);
}
/**
* ice_is_any_vf_in_unicast_promisc - check if any VF(s)
* are in unicast promiscuous mode
......@@ -495,7 +543,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
ice_vf_pre_vsi_rebuild(vf);
ice_vf_rebuild_vsi(vf);
vf->vf_ops->post_vsi_rebuild(vf);
ice_vf_post_vsi_rebuild(vf);
mutex_unlock(&vf->cfg_lock);
}
......@@ -639,14 +687,14 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
ice_vf_pre_vsi_rebuild(vf);
if (vf->vf_ops->vsi_rebuild(vf)) {
if (ice_vf_recreate_vsi(vf)) {
dev_err(dev, "Failed to release and setup the VF%u's VSI\n",
vf->vf_id);
err = -EFAULT;
goto out_unlock;
}
vf->vf_ops->post_vsi_rebuild(vf);
ice_vf_post_vsi_rebuild(vf);
vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi)) {
err = -EINVAL;
......@@ -673,7 +721,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
* ice_set_vf_state_qs_dis - Set VF queues state to disabled
* @vf: pointer to the VF structure
*/
void ice_set_vf_state_qs_dis(struct ice_vf *vf)
static void ice_set_vf_state_qs_dis(struct ice_vf *vf)
{
/* Clear Rx/Tx enabled queues flag */
bitmap_zero(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF);
......@@ -681,8 +729,44 @@ void ice_set_vf_state_qs_dis(struct ice_vf *vf)
clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
}
/**
* ice_set_vf_state_dis - Set VF state to disabled
* @vf: pointer to the VF structure
*/
void ice_set_vf_state_dis(struct ice_vf *vf)
{
ice_set_vf_state_qs_dis(vf);
vf->vf_ops->clear_reset_state(vf);
}
/* Private functions only accessed from other virtualization files */
/**
* ice_initialize_vf_entry - Initialize a VF entry
* @vf: pointer to the VF structure
*/
void ice_initialize_vf_entry(struct ice_vf *vf)
{
struct ice_pf *pf = vf->pf;
struct ice_vfs *vfs;
vfs = &pf->vfs;
/* assign default capabilities */
vf->spoofchk = true;
vf->num_vf_qs = vfs->num_qps_per;
ice_vc_set_default_allowlist(vf);
ice_virtchnl_set_dflt_ops(vf);
/* ctrl_vsi_idx will be set to a valid value only when iAVF
* creates its first fdir rule.
*/
ice_vf_ctrl_invalidate_vsi(vf);
ice_vf_fdir_init(vf);
mutex_init(&vf->cfg_lock);
}
/**
* ice_dis_vf_qs - Disable the VF queues
* @vf: pointer to the VF structure
......@@ -924,18 +1008,18 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf)
vf->num_mac++;
if (is_valid_ether_addr(vf->hw_lan_addr.addr)) {
status = ice_fltr_add_mac(vsi, vf->hw_lan_addr.addr,
if (is_valid_ether_addr(vf->hw_lan_addr)) {
status = ice_fltr_add_mac(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
if (status) {
dev_err(dev, "failed to add default unicast MAC filter %pM for VF %u, error %d\n",
&vf->hw_lan_addr.addr[0], vf->vf_id,
&vf->hw_lan_addr[0], vf->vf_id,
status);
return status;
}
vf->num_mac++;
ether_addr_copy(vf->dev_lan_addr.addr, vf->hw_lan_addr.addr);
ether_addr_copy(vf->dev_lan_addr, vf->hw_lan_addr);
}
return 0;
......@@ -1115,11 +1199,16 @@ void ice_vf_ctrl_vsi_release(struct ice_vf *vf)
*/
struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf)
{
struct ice_port_info *pi = ice_vf_get_port_info(vf);
struct ice_vsi_cfg_params params = {};
struct ice_pf *pf = vf->pf;
struct ice_vsi *vsi;
vsi = ice_vsi_setup(pf, pi, ICE_VSI_CTRL, vf, NULL);
params.type = ICE_VSI_CTRL;
params.pi = ice_vf_get_port_info(vf);
params.vf = vf;
params.flags = ICE_VSI_FLAG_INIT;
vsi = ice_vsi_setup(pf, &params);
if (!vsi) {
dev_err(ice_pf_to_dev(pf), "Failed to create VF control VSI\n");
ice_vf_ctrl_invalidate_vsi(vf);
......@@ -1128,6 +1217,60 @@ struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf)
return vsi;
}
/**
* ice_vf_init_host_cfg - Initialize host admin configuration
* @vf: VF to initialize
* @vsi: the VSI created at initialization
*
* Initialize the VF host configuration. Called during VF creation to setup
* VLAN 0, add the VF VSI broadcast filter, and setup spoof checking. It
* should only be called during VF creation.
*/
int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
{
struct ice_vsi_vlan_ops *vlan_ops;
struct ice_pf *pf = vf->pf;
u8 broadcast[ETH_ALEN];
struct device *dev;
int err;
dev = ice_pf_to_dev(pf);
err = ice_vsi_add_vlan_zero(vsi);
if (err) {
dev_warn(dev, "Failed to add VLAN 0 filter for VF %d\n",
vf->vf_id);
return err;
}
vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
err = vlan_ops->ena_rx_filtering(vsi);
if (err) {
dev_warn(dev, "Failed to enable Rx VLAN filtering for VF %d\n",
vf->vf_id);
return err;
}
eth_broadcast_addr(broadcast);
err = ice_fltr_add_mac(vsi, broadcast, ICE_FWD_TO_VSI);
if (err) {
dev_err(dev, "Failed to add broadcast MAC filter for VF %d, status %d\n",
vf->vf_id, err);
return err;
}
vf->num_mac = 1;
err = ice_vsi_apply_spoofchk(vsi, vf->spoofchk);
if (err) {
dev_warn(dev, "Failed to initialize spoofchk setting for VF %d\n",
vf->vf_id);
return err;
}
return 0;
}
/**
* ice_vf_invalidate_vsi - invalidate vsi_idx/vsi_num to remove VSI access
* @vf: VF to remove access to VSI for
......@@ -1138,6 +1281,24 @@ void ice_vf_invalidate_vsi(struct ice_vf *vf)
vf->lan_vsi_num = ICE_NO_VSI;
}
/**
* ice_vf_vsi_release - Release the VF VSI and invalidate indexes
* @vf: pointer to the VF structure
*
* Release the VF associated with this VSI and then invalidate the VSI
* indexes.
*/
void ice_vf_vsi_release(struct ice_vf *vf)
{
struct ice_vsi *vsi = ice_get_vf_vsi(vf);
if (WARN_ON(!vsi))
return;
ice_vsi_release(vsi);
ice_vf_invalidate_vsi(vf);
}
/**
* ice_vf_set_initialized - VF is ready for VIRTCHNL communication
* @vf: VF to set in initialized state
......
......@@ -56,11 +56,13 @@ struct ice_mdd_vf_events {
struct ice_vf_ops {
enum ice_disq_rst_src reset_type;
void (*free)(struct ice_vf *vf);
void (*clear_reset_state)(struct ice_vf *vf);
void (*clear_mbx_register)(struct ice_vf *vf);
void (*trigger_reset_register)(struct ice_vf *vf, bool is_vflr);
bool (*poll_reset_status)(struct ice_vf *vf);
void (*clear_reset_trigger)(struct ice_vf *vf);
int (*vsi_rebuild)(struct ice_vf *vf);
void (*irq_close)(struct ice_vf *vf);
int (*create_vsi)(struct ice_vf *vf);
void (*post_vsi_rebuild)(struct ice_vf *vf);
};
......@@ -96,8 +98,8 @@ struct ice_vf {
struct ice_sw *vf_sw_id; /* switch ID the VF VSIs connect to */
struct virtchnl_version_info vf_ver;
u32 driver_caps; /* reported by VF driver */
struct virtchnl_ether_addr dev_lan_addr;
struct virtchnl_ether_addr hw_lan_addr;
u8 dev_lan_addr[ETH_ALEN];
u8 hw_lan_addr[ETH_ALEN];
struct ice_time_mac legacy_last_added_umac;
DECLARE_BITMAP(txq_ena, ICE_MAX_RSS_QS_PER_VF);
DECLARE_BITMAP(rxq_ena, ICE_MAX_RSS_QS_PER_VF);
......@@ -213,7 +215,7 @@ u16 ice_get_num_vfs(struct ice_pf *pf);
struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
bool ice_is_vf_disabled(struct ice_vf *vf);
int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
void ice_set_vf_state_qs_dis(struct ice_vf *vf);
void ice_set_vf_state_dis(struct ice_vf *vf);
bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf);
void
ice_vf_get_promisc_masks(struct ice_vf *vf, struct ice_vsi *vsi,
......@@ -259,7 +261,7 @@ static inline int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
return -EOPNOTSUPP;
}
static inline void ice_set_vf_state_qs_dis(struct ice_vf *vf)
static inline void ice_set_vf_state_dis(struct ice_vf *vf)
{
}
......
......@@ -23,6 +23,7 @@
#warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files"
#endif
void ice_initialize_vf_entry(struct ice_vf *vf);
void ice_dis_vf_qs(struct ice_vf *vf);
int ice_check_vf_init(struct ice_vf *vf);
enum virtchnl_status_code ice_err_to_virt_err(int err);
......@@ -35,7 +36,9 @@ void ice_vf_rebuild_host_cfg(struct ice_vf *vf);
void ice_vf_ctrl_invalidate_vsi(struct ice_vf *vf);
void ice_vf_ctrl_vsi_release(struct ice_vf *vf);
struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf);
int ice_vf_init_host_cfg(struct ice_vf *vf, struct ice_vsi *vsi);
void ice_vf_invalidate_vsi(struct ice_vf *vf);
void ice_vf_vsi_release(struct ice_vf *vf);
void ice_vf_set_initialized(struct ice_vf *vf);
#endif /* _ICE_VF_LIB_PRIVATE_H_ */
......@@ -507,7 +507,7 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
vfres->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;
vfres->vsi_res[0].num_queue_pairs = vsi->num_txq;
ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
vf->hw_lan_addr.addr);
vf->hw_lan_addr);
/* match guest capabilities */
vf->driver_caps = vfres->vf_cap_flags;
......@@ -1802,10 +1802,10 @@ ice_vfhw_mac_add(struct ice_vf *vf, struct virtchnl_ether_addr *vc_ether_addr)
* was correctly specified over VIRTCHNL
*/
if ((ice_is_vc_addr_legacy(vc_ether_addr) &&
is_zero_ether_addr(vf->hw_lan_addr.addr)) ||
is_zero_ether_addr(vf->hw_lan_addr)) ||
ice_is_vc_addr_primary(vc_ether_addr)) {
ether_addr_copy(vf->dev_lan_addr.addr, mac_addr);
ether_addr_copy(vf->hw_lan_addr.addr, mac_addr);
ether_addr_copy(vf->dev_lan_addr, mac_addr);
ether_addr_copy(vf->hw_lan_addr, mac_addr);
}
/* hardware and device MACs are already set, but its possible that the
......@@ -1836,7 +1836,7 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
int ret;
/* device MAC already added */
if (ether_addr_equal(mac_addr, vf->dev_lan_addr.addr))
if (ether_addr_equal(mac_addr, vf->dev_lan_addr))
return 0;
if (is_unicast_ether_addr(mac_addr) && !ice_can_vf_change_mac(vf)) {
......@@ -1891,8 +1891,8 @@ ice_update_legacy_cached_mac(struct ice_vf *vf,
ice_is_legacy_umac_expired(&vf->legacy_last_added_umac))
return;
ether_addr_copy(vf->dev_lan_addr.addr, vf->legacy_last_added_umac.addr);
ether_addr_copy(vf->hw_lan_addr.addr, vf->legacy_last_added_umac.addr);
ether_addr_copy(vf->dev_lan_addr, vf->legacy_last_added_umac.addr);
ether_addr_copy(vf->hw_lan_addr, vf->legacy_last_added_umac.addr);
}
/**
......@@ -1906,15 +1906,15 @@ ice_vfhw_mac_del(struct ice_vf *vf, struct virtchnl_ether_addr *vc_ether_addr)
u8 *mac_addr = vc_ether_addr->addr;
if (!is_valid_ether_addr(mac_addr) ||
!ether_addr_equal(vf->dev_lan_addr.addr, mac_addr))
!ether_addr_equal(vf->dev_lan_addr, mac_addr))
return;
/* allow the device MAC to be repopulated in the add flow and don't
* clear the hardware MAC (i.e. hw_lan_addr.addr) here as that is meant
* clear the hardware MAC (i.e. hw_lan_addr) here as that is meant
* to be persistent on VM reboot and across driver unload/load, which
* won't work if we clear the hardware MAC here
*/
eth_zero_addr(vf->dev_lan_addr.addr);
eth_zero_addr(vf->dev_lan_addr);
ice_update_legacy_cached_mac(vf, vc_ether_addr);
}
......@@ -1934,7 +1934,7 @@ ice_vc_del_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
int status;
if (!ice_can_vf_change_mac(vf) &&
ether_addr_equal(vf->dev_lan_addr.addr, mac_addr))
ether_addr_equal(vf->dev_lan_addr, mac_addr))
return 0;
status = ice_fltr_remove_mac(vsi, mac_addr, ICE_FWD_TO_VSI);
......@@ -3733,7 +3733,7 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)
int result;
if (!is_unicast_ether_addr(mac_addr) ||
ether_addr_equal(mac_addr, vf->hw_lan_addr.addr))
ether_addr_equal(mac_addr, vf->hw_lan_addr))
continue;
if (vf->pf_set_mac) {
......
......@@ -113,7 +113,7 @@ ice_vc_fdir_param_check(struct ice_vf *vf, u16 vsi_id)
if (!ice_vc_isvalid_vsi_id(vf, vsi_id))
return -EINVAL;
if (!pf->vsi[vf->lan_vsi_idx])
if (!ice_get_vf_vsi(vf))
return -EINVAL;
return 0;
......@@ -494,7 +494,7 @@ ice_vc_fdir_rem_prof(struct ice_vf *vf, enum ice_fltr_ptype flow, int tun)
vf_prof = fdir->fdir_prof[flow];
vf_vsi = pf->vsi[vf->lan_vsi_idx];
vf_vsi = ice_get_vf_vsi(vf);
if (!vf_vsi) {
dev_dbg(dev, "NULL vf %d vsi pointer\n", vf->vf_id);
return;
......@@ -572,7 +572,7 @@ ice_vc_fdir_write_flow_prof(struct ice_vf *vf, enum ice_fltr_ptype flow,
pf = vf->pf;
dev = ice_pf_to_dev(pf);
hw = &pf->hw;
vf_vsi = pf->vsi[vf->lan_vsi_idx];
vf_vsi = ice_get_vf_vsi(vf);
if (!vf_vsi)
return -EINVAL;
......@@ -1205,7 +1205,7 @@ static int ice_vc_fdir_write_fltr(struct ice_vf *vf,
pf = vf->pf;
dev = ice_pf_to_dev(pf);
hw = &pf->hw;
vsi = pf->vsi[vf->lan_vsi_idx];
vsi = ice_get_vf_vsi(vf);
if (!vsi) {
dev_dbg(dev, "Invalid vsi for VF %d\n", vf->vf_id);
return -EINVAL;
......
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