提交 c84d86a0 编写于 作者: J Jakub Kicinski

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

Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2022-03-14

Jacob Keller says:

The ice_virtchnl_pf.c file has become a single place for a lot of
virtualization functionality. This includes most of the virtchnl message
handling, integration with kernel hooks like the .ndo operations, reset
logic, and more.

We are planning in the future to implement and support Scalable IOV in the
ice driver. To do this, much (but not all) of the code in ice_virtchnl_pf.c
will want to be reused.

Rather than dump all of the Scalable IOV implementation into
ice_virtchnl_pf.c it makes sense to house it in a separate file. But that
still leaves all of the Single Root IOV code littered among more generic
logic.

The long term goal is to re-organize the code such that generic re-usable
code is split into separate files. The ice_sriov.c file would end up
containing all of the Single Root IOV implementation specific details, while
ice_vf_lib.[ch] and ice_virtchnl.[ch] contain the generic pieces.

As a first step, notice that ice_sriov.c currently does not contain much of
the SR-IOV implementation. This is housed primarily in ice_virtchnl_pf.c

The code in ice_sriov.c is really generic and relates to the VF mailbox,
including mailbox overflow detection.

Rename ice_sriov.c to ice_vf_mbx.c, and then rename ice_virtchnl_pf.c to
ice_sriov.c

A later series will finish the refactor by splitting ice_sriov.c into
multiple files, moving the generic code into ice_vf_lib.c and ice_virtchnl.c

To prepare for that series, perform some basic cleanup and other refactors
that we've accumulated during this development cycle.

This series builds on top of the recent hash table refactor work.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: use ice_is_vf_trusted helper function
  ice: log an error message when eswitch fails to configure
  ice: cleanup error logging for ice_ena_vfs
  ice: move ice_set_vf_port_vlan near other .ndo ops
  ice: refactor spoofchk control code in ice_sriov.c
  ice: rename ICE_MAX_VF_COUNT to avoid confusion
  ice: remove unused definitions from ice_sriov.h
  ice: convert vf->vc_ops to a const pointer
  ice: remove circular header dependencies on ice.h
  ice: rename ice_virtchnl_pf.c to ice_sriov.c
  ice: rename ice_sriov.c to ice_vf_mbx.c
====================

Link: https://lore.kernel.org/r/20220315011155.2166817-1-anthony.l.nguyen@intel.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
......@@ -36,9 +36,9 @@ ice-y := ice_main.o \
ice-$(CONFIG_PCI_IOV) += \
ice_virtchnl_allowlist.o \
ice_virtchnl_fdir.o \
ice_sriov.o \
ice_vf_mbx.o \
ice_vf_vsi_vlan_ops.o \
ice_virtchnl_pf.o
ice_sriov.o
ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o
ice-$(CONFIG_TTY) += ice_gnss.o
ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
......
......@@ -52,9 +52,6 @@
#include <net/udp_tunnel.h>
#include <net/vxlan.h>
#include <net/gtp.h>
#if IS_ENABLED(CONFIG_DCB)
#include <scsi/iscsi_proto.h>
#endif /* CONFIG_DCB */
#include "ice_devids.h"
#include "ice_type.h"
#include "ice_txrx.h"
......@@ -64,8 +61,8 @@
#include "ice_flow.h"
#include "ice_sched.h"
#include "ice_idc_int.h"
#include "ice_virtchnl_pf.h"
#include "ice_sriov.h"
#include "ice_vf_mbx.h"
#include "ice_ptp.h"
#include "ice_fdir.h"
#include "ice_xsk.h"
......
......@@ -3,6 +3,9 @@
#ifndef _ICE_ARFS_H_
#define _ICE_ARFS_H_
#include "ice_fdir.h"
enum ice_arfs_fltr_state {
ICE_ARFS_INACTIVE,
ICE_ARFS_ACTIVE,
......
......@@ -5,7 +5,7 @@
#include "ice_base.h"
#include "ice_lib.h"
#include "ice_dcb_lib.h"
#include "ice_virtchnl_pf.h"
#include "ice_sriov.h"
static bool ice_alloc_rx_buf_zc(struct ice_rx_ring *rx_ring)
{
......
......@@ -6,12 +6,12 @@
#include <linux/bitfield.h>
#include "ice.h"
#include "ice_type.h"
#include "ice_nvm.h"
#include "ice_flex_pipe.h"
#include "ice_switch.h"
#include <linux/avf/virtchnl.h>
#include "ice_switch.h"
#include "ice_fdir.h"
#define ICE_SQ_SEND_DELAY_TIME_MS 10
#define ICE_SQ_SEND_MAX_EXECUTE 3
......
......@@ -5,6 +5,7 @@
#define _ICE_DCB_H_
#include "ice_type.h"
#include <scsi/iscsi_proto.h>
#define ICE_DCBX_STATUS_NOT_STARTED 0
#define ICE_DCBX_STATUS_IN_PROGRESS 1
......
......@@ -4,6 +4,7 @@
#include "ice_common.h"
#include "ice_flex_pipe.h"
#include "ice_flow.h"
#include "ice.h"
/* For supporting double VLAN mode, it is necessary to enable or disable certain
* boost tcam entries. The metadata labels names that match the following
......
......@@ -3,6 +3,7 @@
#include "ice_common.h"
#include "ice_flow.h"
#include <net/gre.h>
/* Describe properties of a protocol header field */
struct ice_flow_field_info {
......
......@@ -4,6 +4,8 @@
#ifndef _ICE_FLOW_H_
#define _ICE_FLOW_H_
#include "ice_flex_type.h"
#define ICE_FLOW_ENTRY_HANDLE_INVAL 0
#define ICE_FLOW_FLD_OFF_INVAL 0xffff
......
......@@ -5,7 +5,6 @@
#define _ICE_IDC_INT_H_
#include <linux/net/intel/iidc.h>
#include "ice.h"
struct ice_pf;
......
......@@ -48,6 +48,21 @@ static DEFINE_IDA(ice_aux_ida);
DEFINE_STATIC_KEY_FALSE(ice_xdp_locking_key);
EXPORT_SYMBOL(ice_xdp_locking_key);
/**
* ice_hw_to_dev - Get device pointer from the hardware structure
* @hw: pointer to the device HW structure
*
* Used to access the device pointer from compilation units which can't easily
* include the definition of struct ice_pf without leading to circular header
* dependencies.
*/
struct device *ice_hw_to_dev(struct ice_hw *hw)
{
struct ice_pf *pf = container_of(hw, struct ice_pf, hw);
return &pf->pdev->dev;
}
static struct workqueue_struct *ice_wq;
static const struct net_device_ops ice_netdev_safe_mode_ops;
static const struct net_device_ops ice_netdev_ops;
......@@ -3739,7 +3754,7 @@ static void ice_set_pf_caps(struct ice_pf *pf)
if (func_caps->common_cap.sr_iov_1_1) {
set_bit(ICE_FLAG_SRIOV_CAPABLE, pf->flags);
pf->vfs.num_supported = min_t(int, func_caps->num_allocd_vfs,
ICE_MAX_VF_COUNT);
ICE_MAX_SRIOV_VFS);
}
clear_bit(ICE_FLAG_RSS_ENA, pf->flags);
if (func_caps->common_cap.rss_table_size)
......
......@@ -5,7 +5,14 @@
#define _ICE_OSDEP_H_
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/pci_ids.h>
#ifndef CONFIG_64BIT
#include <linux/io-64-nonatomic-lo-hi.h>
#endif
......@@ -25,8 +32,8 @@ struct ice_dma_mem {
size_t size;
};
#define ice_hw_to_dev(ptr) \
(&(container_of((ptr), struct ice_pf, hw))->pdev->dev)
struct ice_hw;
struct device *ice_hw_to_dev(struct ice_hw *hw);
#ifdef CONFIG_DYNAMIC_DEBUG
#define ice_debug(hw, type, fmt, args...) \
......
......@@ -4,7 +4,7 @@
#include "ice.h"
#include "ice_eswitch.h"
#include "ice_devlink.h"
#include "ice_virtchnl_pf.h"
#include "ice_sriov.h"
#include "ice_tc_lib.h"
/**
......@@ -339,7 +339,7 @@ static int ice_repr_add(struct ice_vf *vf)
devlink_port_type_eth_set(&vf->devlink_port, repr->netdev);
ice_vc_change_ops_to_repr(&vf->vc_ops);
ice_virtchnl_set_repr_ops(vf);
return 0;
......@@ -384,7 +384,7 @@ static void ice_repr_rem(struct ice_vf *vf)
kfree(vf->repr);
vf->repr = NULL;
ice_vc_set_dflt_vf_ops(&vf->vc_ops);
ice_virtchnl_set_dflt_ops(vf);
}
/**
......
......@@ -5,7 +5,6 @@
#define _ICE_REPR_H_
#include <net/dst_metadata.h>
#include "ice.h"
struct ice_repr {
struct ice_vsi *src_vsi;
......
......@@ -3,50 +3,428 @@
#ifndef _ICE_SRIOV_H_
#define _ICE_SRIOV_H_
#include "ice_virtchnl_fdir.h"
#include "ice_vsi_vlan_ops.h"
#include "ice_type.h"
#include "ice_controlq.h"
/* Restrict number of MAC Addr and VLAN that non-trusted VF can programmed */
#define ICE_MAX_VLAN_PER_VF 8
/* MAC filters: 1 is reserved for the VF's default/perm_addr/LAA MAC, 1 for
* broadcast, and 16 for additional unicast/multicast filters
*/
#define ICE_MAX_MACADDR_PER_VF 18
/* Static VF transaction/status register def */
#define VF_DEVICE_STATUS 0xAA
#define VF_TRANS_PENDING_M 0x20
/* wait defines for polling PF_PCI_CIAD register status */
#define ICE_PCI_CIAD_WAIT_COUNT 100
#define ICE_PCI_CIAD_WAIT_DELAY_US 1
/* VF resource constraints */
#define ICE_MAX_SRIOV_VFS 256
#define ICE_MIN_QS_PER_VF 1
#define ICE_NONQ_VECS_VF 1
#define ICE_MAX_RSS_QS_PER_VF 16
#define ICE_NUM_VF_MSIX_MED 17
#define ICE_NUM_VF_MSIX_SMALL 5
#define ICE_NUM_VF_MSIX_MULTIQ_MIN 3
#define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1)
#define ICE_MAX_VF_RESET_TRIES 40
#define ICE_MAX_VF_RESET_SLEEP_MS 20
/* Defining the mailbox message threshold as 63 asynchronous
* pending messages. Normal VF functionality does not require
* sending more than 63 asynchronous pending message.
/* VF Hash Table access functions
*
* These functions provide abstraction for interacting with the VF hash table.
* In general, direct access to the hash table should be avoided outside of
* these functions where possible.
*
* The VF entries in the hash table are protected by reference counting to
* track lifetime of accesses from the table. The ice_get_vf_by_id() function
* obtains a reference to the VF structure which must be dropped by using
* ice_put_vf().
*/
#define ICE_ASYNC_VF_MSG_THRESHOLD 63
/**
* ice_for_each_vf - Iterate over each VF entry
* @pf: pointer to the PF private structure
* @bkt: bucket index used for iteration
* @vf: pointer to the VF entry currently being processed in the loop.
*
* The bkt variable is an unsigned integer iterator used to traverse the VF
* entries. It is *not* guaranteed to be the VF's vf_id. Do not assume it is.
* Use vf->vf_id to get the id number if needed.
*
* The caller is expected to be under the table_lock mutex for the entire
* loop. Use this iterator if your loop is long or if it might sleep.
*/
#define ice_for_each_vf(pf, bkt, vf) \
hash_for_each((pf)->vfs.table, (bkt), (vf), entry)
/**
* ice_for_each_vf_rcu - Iterate over each VF entry protected by RCU
* @pf: pointer to the PF private structure
* @bkt: bucket index used for iteration
* @vf: pointer to the VF entry currently being processed in the loop.
*
* The bkt variable is an unsigned integer iterator used to traverse the VF
* entries. It is *not* guaranteed to be the VF's vf_id. Do not assume it is.
* Use vf->vf_id to get the id number if needed.
*
* The caller is expected to be under rcu_read_lock() for the entire loop.
* Only use this iterator if your loop is short and you can guarantee it does
* not sleep.
*/
#define ice_for_each_vf_rcu(pf, bkt, vf) \
hash_for_each_rcu((pf)->vfs.table, (bkt), (vf), entry)
/* Specific VF states */
enum ice_vf_states {
ICE_VF_STATE_INIT = 0, /* PF is initializing VF */
ICE_VF_STATE_ACTIVE, /* VF resources are allocated for use */
ICE_VF_STATE_QS_ENA, /* VF queue(s) enabled */
ICE_VF_STATE_DIS,
ICE_VF_STATE_MC_PROMISC,
ICE_VF_STATE_UC_PROMISC,
ICE_VF_STATES_NBITS
};
/* VF capabilities */
enum ice_virtchnl_cap {
ICE_VIRTCHNL_VF_CAP_PRIVILEGE = 0,
};
struct ice_time_mac {
unsigned long time_modified;
u8 addr[ETH_ALEN];
};
/* VF MDD events print structure */
struct ice_mdd_vf_events {
u16 count; /* total count of Rx|Tx events */
/* count number of the last printed event */
u16 last_printed;
};
struct ice_vf;
struct ice_virtchnl_ops {
int (*get_ver_msg)(struct ice_vf *vf, u8 *msg);
int (*get_vf_res_msg)(struct ice_vf *vf, u8 *msg);
void (*reset_vf)(struct ice_vf *vf);
int (*add_mac_addr_msg)(struct ice_vf *vf, u8 *msg);
int (*del_mac_addr_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*request_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_irq_map_msg)(struct ice_vf *vf, u8 *msg);
int (*config_rss_key)(struct ice_vf *vf, u8 *msg);
int (*config_rss_lut)(struct ice_vf *vf, u8 *msg);
int (*get_stats_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_promiscuous_mode_msg)(struct ice_vf *vf, u8 *msg);
int (*add_vlan_msg)(struct ice_vf *vf, u8 *msg);
int (*remove_vlan_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_stripping)(struct ice_vf *vf);
int (*dis_vlan_stripping)(struct ice_vf *vf);
int (*handle_rss_cfg_msg)(struct ice_vf *vf, u8 *msg, bool add);
int (*add_fdir_fltr_msg)(struct ice_vf *vf, u8 *msg);
int (*del_fdir_fltr_msg)(struct ice_vf *vf, u8 *msg);
int (*get_offload_vlan_v2_caps)(struct ice_vf *vf);
int (*add_vlan_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*remove_vlan_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_stripping_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_vlan_stripping_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_insertion_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_vlan_insertion_v2_msg)(struct ice_vf *vf, u8 *msg);
};
/* Virtchnl/SR-IOV config info */
struct ice_vfs {
DECLARE_HASHTABLE(table, 8); /* table of VF entries */
struct mutex table_lock; /* Lock for protecting the hash table */
u16 num_supported; /* max supported VFs on this PF */
u16 num_qps_per; /* number of queue pairs per VF */
u16 num_msix_per; /* number of MSI-X vectors per VF */
unsigned long last_printed_mdd_jiffies; /* MDD message rate limit */
DECLARE_BITMAP(malvfs, ICE_MAX_SRIOV_VFS); /* malicious VF indicator */
};
/* VF information structure */
struct ice_vf {
struct hlist_node entry;
struct rcu_head rcu;
struct kref refcnt;
struct ice_pf *pf;
/* Used during virtchnl message handling and NDO ops against the VF
* that will trigger a VFR
*/
struct mutex cfg_lock;
u16 vf_id; /* VF ID in the PF space */
u16 lan_vsi_idx; /* index into PF struct */
u16 ctrl_vsi_idx;
struct ice_vf_fdir fdir;
/* first vector index of this VF in the PF space */
int first_vector_idx;
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;
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);
struct ice_vlan port_vlan_info; /* Port VLAN ID, QoS, and TPID */
struct virtchnl_vlan_caps vlan_v2_caps;
u8 pf_set_mac:1; /* VF MAC address set by VMM admin */
u8 trusted:1;
u8 spoofchk:1;
u8 link_forced:1;
u8 link_up:1; /* only valid if VF link is forced */
/* VSI indices - actual VSI pointers are maintained in the PF structure
* When assigned, these will be non-zero, because VSI 0 is always
* the main LAN VSI for the PF.
*/
u16 lan_vsi_num; /* ID as used by firmware */
unsigned int min_tx_rate; /* Minimum Tx bandwidth limit in Mbps */
unsigned int max_tx_rate; /* Maximum Tx bandwidth limit in Mbps */
DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
unsigned long vf_caps; /* VF's adv. capabilities */
u8 num_req_qs; /* num of queue pairs requested by VF */
u16 num_mac;
u16 num_vf_qs; /* num of queue configured per VF */
struct ice_mdd_vf_events mdd_rx_events;
struct ice_mdd_vf_events mdd_tx_events;
DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
struct ice_repr *repr;
const struct ice_virtchnl_ops *virtchnl_ops;
/* devlink port data */
struct devlink_port devlink_port;
};
#ifdef CONFIG_PCI_IOV
struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id);
void ice_put_vf(struct ice_vf *vf);
bool ice_has_vfs(struct ice_pf *pf);
u16 ice_get_num_vfs(struct ice_pf *pf);
struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
void ice_process_vflr_event(struct ice_pf *pf);
int ice_sriov_configure(struct pci_dev *pdev, int num_vfs);
int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
int
ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
u8 *msg, u16 msglen, struct ice_sq_cd *cd);
ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi);
void ice_free_vfs(struct ice_pf *pf);
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event);
void ice_vc_notify_link_state(struct ice_pf *pf);
void ice_vc_notify_reset(struct ice_pf *pf);
void ice_vc_notify_vf_link_state(struct ice_vf *vf);
void ice_virtchnl_set_repr_ops(struct ice_vf *vf);
void ice_virtchnl_set_dflt_ops(struct ice_vf *vf);
bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr);
bool ice_reset_vf(struct ice_vf *vf, bool is_vflr);
void ice_restore_all_vfs_msi_state(struct pci_dev *pdev);
bool
ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event,
u16 num_msg_proc, u16 num_msg_pending);
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
int
ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
u16 vf_id, bool *is_mal_vf);
ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
__be16 vlan_proto);
int
ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id);
int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count);
void ice_mbx_deinit_snapshot(struct ice_hw *hw);
ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
int max_tx_rate);
int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted);
int ice_set_vf_link_state(struct net_device *netdev, int vf_id, int link_state);
int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
bool ice_is_vf_disabled(struct ice_vf *vf);
int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena);
int ice_calc_vf_reg_idx(struct ice_vf *vf, struct ice_q_vector *q_vector);
void ice_set_vf_state_qs_dis(struct ice_vf *vf);
int
ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id, bool *report_malvf);
ice_get_vf_stats(struct net_device *netdev, int vf_id,
struct ifla_vf_stats *vf_stats);
bool ice_is_any_vf_in_promisc(struct ice_pf *pf);
void
ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event);
void ice_print_vfs_mdd_events(struct ice_pf *pf);
void ice_print_vf_rx_mdd_event(struct ice_vf *vf);
bool
ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto);
struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf);
int
ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,
enum virtchnl_status_code v_retval, u8 *msg, u16 msglen);
bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id);
bool ice_vf_is_port_vlan_ena(struct ice_vf *vf);
#else /* CONFIG_PCI_IOV */
static inline int
ice_aq_send_msg_to_vf(struct ice_hw __always_unused *hw,
u16 __always_unused vfid, u32 __always_unused v_opcode,
u32 __always_unused v_retval, u8 __always_unused *msg,
u16 __always_unused msglen,
struct ice_sq_cd __always_unused *cd)
static inline struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id)
{
return NULL;
}
static inline void ice_put_vf(struct ice_vf *vf)
{
}
static inline bool ice_has_vfs(struct ice_pf *pf)
{
return false;
}
static inline u16 ice_get_num_vfs(struct ice_pf *pf)
{
return 0;
}
static inline u32
ice_conv_link_speed_to_virtchnl(bool __always_unused adv_link_support,
u16 __always_unused link_speed)
static inline void ice_process_vflr_event(struct ice_pf *pf) { }
static inline void ice_free_vfs(struct ice_pf *pf) { }
static inline
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) { }
static inline void ice_vc_notify_link_state(struct ice_pf *pf) { }
static inline void ice_vc_notify_reset(struct ice_pf *pf) { }
static inline void ice_vc_notify_vf_link_state(struct ice_vf *vf) { }
static inline void ice_virtchnl_set_repr_ops(struct ice_vf *vf) { }
static inline void ice_virtchnl_set_dflt_ops(struct ice_vf *vf) { }
static inline void ice_set_vf_state_qs_dis(struct ice_vf *vf) { }
static inline
void ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) { }
static inline void ice_print_vfs_mdd_events(struct ice_pf *pf) { }
static inline void ice_print_vf_rx_mdd_event(struct ice_vf *vf) { }
static inline void ice_restore_all_vfs_msi_state(struct pci_dev *pdev) { }
static inline int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
{
return -EOPNOTSUPP;
}
static inline bool ice_is_vf_disabled(struct ice_vf *vf)
{
return true;
}
static inline struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf)
{
return NULL;
}
static inline bool
ice_is_malicious_vf(struct ice_pf __always_unused *pf,
struct ice_rq_event_info __always_unused *event,
u16 __always_unused num_msg_proc,
u16 __always_unused num_msg_pending)
{
return false;
}
static inline bool
ice_reset_all_vfs(struct ice_pf __always_unused *pf,
bool __always_unused is_vflr)
{
return true;
}
static inline bool
ice_reset_vf(struct ice_vf __always_unused *vf, bool __always_unused is_vflr)
{
return true;
}
static inline int
ice_sriov_configure(struct pci_dev __always_unused *pdev,
int __always_unused num_vfs)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_mac(struct net_device __always_unused *netdev,
int __always_unused vf_id, u8 __always_unused *mac)
{
return -EOPNOTSUPP;
}
static inline int
ice_get_vf_cfg(struct net_device __always_unused *netdev,
int __always_unused vf_id,
struct ifla_vf_info __always_unused *ivi)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_trust(struct net_device __always_unused *netdev,
int __always_unused vf_id, bool __always_unused trusted)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_port_vlan(struct net_device __always_unused *netdev,
int __always_unused vf_id, u16 __always_unused vid,
u8 __always_unused qos, __be16 __always_unused v_proto)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_spoofchk(struct net_device __always_unused *netdev,
int __always_unused vf_id, bool __always_unused ena)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_link_state(struct net_device __always_unused *netdev,
int __always_unused vf_id, int __always_unused link_state)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_bw(struct net_device __always_unused *netdev,
int __always_unused vf_id, int __always_unused min_tx_rate,
int __always_unused max_tx_rate)
{
return -EOPNOTSUPP;
}
static inline int
ice_calc_vf_reg_idx(struct ice_vf __always_unused *vf,
struct ice_q_vector __always_unused *q_vector)
{
return 0;
}
static inline int
ice_get_vf_stats(struct net_device __always_unused *netdev,
int __always_unused vf_id,
struct ifla_vf_stats __always_unused *vf_stats)
{
return -EOPNOTSUPP;
}
static inline bool ice_is_any_vf_in_promisc(struct ice_pf __always_unused *pf)
{
return false;
}
static inline bool ice_vf_is_port_vlan_ena(struct ice_vf __always_unused *vf)
{
return false;
}
#endif /* CONFIG_PCI_IOV */
#endif /* _ICE_SRIOV_H_ */
......@@ -9,6 +9,7 @@
#define ICE_CHNL_MAX_TC 16
#include "ice_hw_autogen.h"
#include "ice_devids.h"
#include "ice_osdep.h"
#include "ice_controlq.h"
#include "ice_lan_tx_rx.h"
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018, Intel Corporation. */
#include "ice_common.h"
#include "ice_vf_mbx.h"
/**
* ice_aq_send_msg_to_vf
* @hw: pointer to the hardware structure
* @vfid: VF ID to send msg
* @v_opcode: opcodes for VF-PF communication
* @v_retval: return error code
* @msg: pointer to the msg buffer
* @msglen: msg length
* @cd: pointer to command details
*
* Send message to VF driver (0x0802) using mailbox
* queue and asynchronously sending message via
* ice_sq_send_cmd() function
*/
int
ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
u8 *msg, u16 msglen, struct ice_sq_cd *cd)
{
struct ice_aqc_pf_vf_msg *cmd;
struct ice_aq_desc desc;
ice_fill_dflt_direct_cmd_desc(&desc, ice_mbx_opc_send_msg_to_vf);
cmd = &desc.params.virt;
cmd->id = cpu_to_le32(vfid);
desc.cookie_high = cpu_to_le32(v_opcode);
desc.cookie_low = cpu_to_le32(v_retval);
if (msglen)
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
return ice_sq_send_cmd(hw, &hw->mailboxq, &desc, msg, msglen, cd);
}
/**
* ice_conv_link_speed_to_virtchnl
* @adv_link_support: determines the format of the returned link speed
* @link_speed: variable containing the link_speed to be converted
*
* Convert link speed supported by HW to link speed supported by virtchnl.
* If adv_link_support is true, then return link speed in Mbps. Else return
* link speed as a VIRTCHNL_LINK_SPEED_* casted to a u32. Note that the caller
* needs to cast back to an enum virtchnl_link_speed in the case where
* adv_link_support is false, but when adv_link_support is true the caller can
* expect the speed in Mbps.
*/
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
{
u32 speed;
if (adv_link_support)
switch (link_speed) {
case ICE_AQ_LINK_SPEED_10MB:
speed = ICE_LINK_SPEED_10MBPS;
break;
case ICE_AQ_LINK_SPEED_100MB:
speed = ICE_LINK_SPEED_100MBPS;
break;
case ICE_AQ_LINK_SPEED_1000MB:
speed = ICE_LINK_SPEED_1000MBPS;
break;
case ICE_AQ_LINK_SPEED_2500MB:
speed = ICE_LINK_SPEED_2500MBPS;
break;
case ICE_AQ_LINK_SPEED_5GB:
speed = ICE_LINK_SPEED_5000MBPS;
break;
case ICE_AQ_LINK_SPEED_10GB:
speed = ICE_LINK_SPEED_10000MBPS;
break;
case ICE_AQ_LINK_SPEED_20GB:
speed = ICE_LINK_SPEED_20000MBPS;
break;
case ICE_AQ_LINK_SPEED_25GB:
speed = ICE_LINK_SPEED_25000MBPS;
break;
case ICE_AQ_LINK_SPEED_40GB:
speed = ICE_LINK_SPEED_40000MBPS;
break;
case ICE_AQ_LINK_SPEED_50GB:
speed = ICE_LINK_SPEED_50000MBPS;
break;
case ICE_AQ_LINK_SPEED_100GB:
speed = ICE_LINK_SPEED_100000MBPS;
break;
default:
speed = ICE_LINK_SPEED_UNKNOWN;
break;
}
else
/* Virtchnl speeds are not defined for every speed supported in
* the hardware. To maintain compatibility with older AVF
* drivers, while reporting the speed the new speed values are
* resolved to the closest known virtchnl speeds
*/
switch (link_speed) {
case ICE_AQ_LINK_SPEED_10MB:
case ICE_AQ_LINK_SPEED_100MB:
speed = (u32)VIRTCHNL_LINK_SPEED_100MB;
break;
case ICE_AQ_LINK_SPEED_1000MB:
case ICE_AQ_LINK_SPEED_2500MB:
case ICE_AQ_LINK_SPEED_5GB:
speed = (u32)VIRTCHNL_LINK_SPEED_1GB;
break;
case ICE_AQ_LINK_SPEED_10GB:
speed = (u32)VIRTCHNL_LINK_SPEED_10GB;
break;
case ICE_AQ_LINK_SPEED_20GB:
speed = (u32)VIRTCHNL_LINK_SPEED_20GB;
break;
case ICE_AQ_LINK_SPEED_25GB:
speed = (u32)VIRTCHNL_LINK_SPEED_25GB;
break;
case ICE_AQ_LINK_SPEED_40GB:
case ICE_AQ_LINK_SPEED_50GB:
case ICE_AQ_LINK_SPEED_100GB:
speed = (u32)VIRTCHNL_LINK_SPEED_40GB;
break;
default:
speed = (u32)VIRTCHNL_LINK_SPEED_UNKNOWN;
break;
}
return speed;
}
/* The mailbox overflow detection algorithm helps to check if there
* is a possibility of a malicious VF transmitting too many MBX messages to the
* PF.
* 1. The mailbox snapshot structure, ice_mbx_snapshot, is initialized during
* driver initialization in ice_init_hw() using ice_mbx_init_snapshot().
* The struct ice_mbx_snapshot helps to track and traverse a static window of
* messages within the mailbox queue while looking for a malicious VF.
*
* 2. When the caller starts processing its mailbox queue in response to an
* interrupt, the structure ice_mbx_snapshot is expected to be cleared before
* the algorithm can be run for the first time for that interrupt. This can be
* done via ice_mbx_reset_snapshot().
*
* 3. For every message read by the caller from the MBX Queue, the caller must
* call the detection algorithm's entry function ice_mbx_vf_state_handler().
* Before every call to ice_mbx_vf_state_handler() the struct ice_mbx_data is
* filled as it is required to be passed to the algorithm.
*
* 4. Every time a message is read from the MBX queue, a VFId is received which
* is passed to the state handler. The boolean output is_malvf of the state
* handler ice_mbx_vf_state_handler() serves as an indicator to the caller
* whether this VF is malicious or not.
*
* 5. When a VF is identified to be malicious, the caller can send a message
* to the system administrator. The caller can invoke ice_mbx_report_malvf()
* to help determine if a malicious VF is to be reported or not. This function
* requires the caller to maintain a global bitmap to track all malicious VFs
* and pass that to ice_mbx_report_malvf() along with the VFID which was identified
* to be malicious by ice_mbx_vf_state_handler().
*
* 6. The global bitmap maintained by PF can be cleared completely if PF is in
* reset or the bit corresponding to a VF can be cleared if that VF is in reset.
* When a VF is shut down and brought back up, we assume that the new VF
* brought up is not malicious and hence report it if found malicious.
*
* 7. The function ice_mbx_reset_snapshot() is called to reset the information
* in ice_mbx_snapshot for every new mailbox interrupt handled.
*
* 8. The memory allocated for variables in ice_mbx_snapshot is de-allocated
* when driver is unloaded.
*/
#define ICE_RQ_DATA_MASK(rq_data) ((rq_data) & PF_MBX_ARQH_ARQH_M)
/* Using the highest value for an unsigned 16-bit value 0xFFFF to indicate that
* the max messages check must be ignored in the algorithm
*/
#define ICE_IGNORE_MAX_MSG_CNT 0xFFFF
/**
* ice_mbx_traverse - Pass through mailbox snapshot
* @hw: pointer to the HW struct
* @new_state: new algorithm state
*
* Traversing the mailbox static snapshot without checking
* for malicious VFs.
*/
static void
ice_mbx_traverse(struct ice_hw *hw,
enum ice_mbx_snapshot_state *new_state)
{
struct ice_mbx_snap_buffer_data *snap_buf;
u32 num_iterations;
snap_buf = &hw->mbx_snapshot.mbx_buf;
/* As mailbox buffer is circular, applying a mask
* on the incremented iteration count.
*/
num_iterations = ICE_RQ_DATA_MASK(++snap_buf->num_iterations);
/* Checking either of the below conditions to exit snapshot traversal:
* Condition-1: If the number of iterations in the mailbox is equal to
* the mailbox head which would indicate that we have reached the end
* of the static snapshot.
* Condition-2: If the maximum messages serviced in the mailbox for a
* given interrupt is the highest possible value then there is no need
* to check if the number of messages processed is equal to it. If not
* check if the number of messages processed is greater than or equal
* to the maximum number of mailbox entries serviced in current work item.
*/
if (num_iterations == snap_buf->head ||
(snap_buf->max_num_msgs_mbx < ICE_IGNORE_MAX_MSG_CNT &&
++snap_buf->num_msg_proc >= snap_buf->max_num_msgs_mbx))
*new_state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
}
/**
* ice_mbx_detect_malvf - Detect malicious VF in snapshot
* @hw: pointer to the HW struct
* @vf_id: relative virtual function ID
* @new_state: new algorithm state
* @is_malvf: boolean output to indicate if VF is malicious
*
* This function tracks the number of asynchronous messages
* sent per VF and marks the VF as malicious if it exceeds
* the permissible number of messages to send.
*/
static int
ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,
enum ice_mbx_snapshot_state *new_state,
bool *is_malvf)
{
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
if (vf_id >= snap->mbx_vf.vfcntr_len)
return -EIO;
/* increment the message count in the VF array */
snap->mbx_vf.vf_cntr[vf_id]++;
if (snap->mbx_vf.vf_cntr[vf_id] >= ICE_ASYNC_VF_MSG_THRESHOLD)
*is_malvf = true;
/* continue to iterate through the mailbox snapshot */
ice_mbx_traverse(hw, new_state);
return 0;
}
/**
* ice_mbx_reset_snapshot - Reset mailbox snapshot structure
* @snap: pointer to mailbox snapshot structure in the ice_hw struct
*
* Reset the mailbox snapshot structure and clear VF counter array.
*/
static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap)
{
u32 vfcntr_len;
if (!snap || !snap->mbx_vf.vf_cntr)
return;
/* Clear VF counters. */
vfcntr_len = snap->mbx_vf.vfcntr_len;
if (vfcntr_len)
memset(snap->mbx_vf.vf_cntr, 0,
(vfcntr_len * sizeof(*snap->mbx_vf.vf_cntr)));
/* Reset mailbox snapshot for a new capture. */
memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
}
/**
* ice_mbx_vf_state_handler - Handle states of the overflow algorithm
* @hw: pointer to the HW struct
* @mbx_data: pointer to structure containing mailbox data
* @vf_id: relative virtual function (VF) ID
* @is_malvf: boolean output to indicate if VF is malicious
*
* The function serves as an entry point for the malicious VF
* detection algorithm by handling the different states and state
* transitions of the algorithm:
* New snapshot: This state is entered when creating a new static
* snapshot. The data from any previous mailbox snapshot is
* cleared and a new capture of the mailbox head and tail is
* logged. This will be the new static snapshot to detect
* asynchronous messages sent by VFs. On capturing the snapshot
* and depending on whether the number of pending messages in that
* snapshot exceed the watermark value, the state machine enters
* traverse or detect states.
* Traverse: If pending message count is below watermark then iterate
* through the snapshot without any action on VF.
* Detect: If pending message count exceeds watermark traverse
* the static snapshot and look for a malicious VF.
*/
int
ice_mbx_vf_state_handler(struct ice_hw *hw,
struct ice_mbx_data *mbx_data, u16 vf_id,
bool *is_malvf)
{
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
struct ice_mbx_snap_buffer_data *snap_buf;
struct ice_ctl_q_info *cq = &hw->mailboxq;
enum ice_mbx_snapshot_state new_state;
int status = 0;
if (!is_malvf || !mbx_data)
return -EINVAL;
/* When entering the mailbox state machine assume that the VF
* is not malicious until detected.
*/
*is_malvf = false;
/* Checking if max messages allowed to be processed while servicing current
* interrupt is not less than the defined AVF message threshold.
*/
if (mbx_data->max_num_msgs_mbx <= ICE_ASYNC_VF_MSG_THRESHOLD)
return -EINVAL;
/* The watermark value should not be lesser than the threshold limit
* set for the number of asynchronous messages a VF can send to mailbox
* nor should it be greater than the maximum number of messages in the
* mailbox serviced in current interrupt.
*/
if (mbx_data->async_watermark_val < ICE_ASYNC_VF_MSG_THRESHOLD ||
mbx_data->async_watermark_val > mbx_data->max_num_msgs_mbx)
return -EINVAL;
new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
snap_buf = &snap->mbx_buf;
switch (snap_buf->state) {
case ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT:
/* Clear any previously held data in mailbox snapshot structure. */
ice_mbx_reset_snapshot(snap);
/* Collect the pending ARQ count, number of messages processed and
* the maximum number of messages allowed to be processed from the
* Mailbox for current interrupt.
*/
snap_buf->num_pending_arq = mbx_data->num_pending_arq;
snap_buf->num_msg_proc = mbx_data->num_msg_proc;
snap_buf->max_num_msgs_mbx = mbx_data->max_num_msgs_mbx;
/* Capture a new static snapshot of the mailbox by logging the
* head and tail of snapshot and set num_iterations to the tail
* value to mark the start of the iteration through the snapshot.
*/
snap_buf->head = ICE_RQ_DATA_MASK(cq->rq.next_to_clean +
mbx_data->num_pending_arq);
snap_buf->tail = ICE_RQ_DATA_MASK(cq->rq.next_to_clean - 1);
snap_buf->num_iterations = snap_buf->tail;
/* Pending ARQ messages returned by ice_clean_rq_elem
* is the difference between the head and tail of the
* mailbox queue. Comparing this value against the watermark
* helps to check if we potentially have malicious VFs.
*/
if (snap_buf->num_pending_arq >=
mbx_data->async_watermark_val) {
new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
} else {
new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
ice_mbx_traverse(hw, &new_state);
}
break;
case ICE_MAL_VF_DETECT_STATE_TRAVERSE:
new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
ice_mbx_traverse(hw, &new_state);
break;
case ICE_MAL_VF_DETECT_STATE_DETECT:
new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
break;
default:
new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
status = -EIO;
}
snap_buf->state = new_state;
return status;
}
/**
* ice_mbx_report_malvf - Track and note malicious VF
* @hw: pointer to the HW struct
* @all_malvfs: all malicious VFs tracked by PF
* @bitmap_len: length of bitmap in bits
* @vf_id: relative virtual function ID of the malicious VF
* @report_malvf: boolean to indicate if malicious VF must be reported
*
* This function will update a bitmap that keeps track of the malicious
* VFs attached to the PF. A malicious VF must be reported only once if
* discovered between VF resets or loading so the function checks
* the input vf_id against the bitmap to verify if the VF has been
* detected in any previous mailbox iterations.
*/
int
ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id, bool *report_malvf)
{
if (!all_malvfs || !report_malvf)
return -EINVAL;
*report_malvf = false;
if (bitmap_len < hw->mbx_snapshot.mbx_vf.vfcntr_len)
return -EINVAL;
if (vf_id >= bitmap_len)
return -EIO;
/* If the vf_id is found in the bitmap set bit and boolean to true */
if (!test_and_set_bit(vf_id, all_malvfs))
*report_malvf = true;
return 0;
}
/**
* ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID
* @snap: pointer to the mailbox snapshot structure
* @all_malvfs: all malicious VFs tracked by PF
* @bitmap_len: length of bitmap in bits
* @vf_id: relative virtual function ID of the malicious VF
*
* In case of a VF reset, this function can be called to clear
* the bit corresponding to the VF ID in the bitmap tracking all
* malicious VFs attached to the PF. The function also clears the
* VF counter array at the index of the VF ID. This is to ensure
* that the new VF loaded is not considered malicious before going
* through the overflow detection algorithm.
*/
int
ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id)
{
if (!snap || !all_malvfs)
return -EINVAL;
if (bitmap_len < snap->mbx_vf.vfcntr_len)
return -EINVAL;
/* Ensure VF ID value is not larger than bitmap or VF counter length */
if (vf_id >= bitmap_len || vf_id >= snap->mbx_vf.vfcntr_len)
return -EIO;
/* Clear VF ID bit in the bitmap tracking malicious VFs attached to PF */
clear_bit(vf_id, all_malvfs);
/* Clear the VF counter in the mailbox snapshot structure for that VF ID.
* This is to ensure that if a VF is unloaded and a new one brought back
* up with the same VF ID for a snapshot currently in traversal or detect
* state the counter for that VF ID does not increment on top of existing
* values in the mailbox overflow detection algorithm.
*/
snap->mbx_vf.vf_cntr[vf_id] = 0;
return 0;
}
/**
* ice_mbx_init_snapshot - Initialize mailbox snapshot structure
* @hw: pointer to the hardware structure
* @vf_count: number of VFs allocated on a PF
*
* Clear the mailbox snapshot structure and allocate memory
* for the VF counter array based on the number of VFs allocated
* on that PF.
*
* Assumption: This function will assume ice_get_caps() has already been
* called to ensure that the vf_count can be compared against the number
* of VFs supported as defined in the functional capabilities of the device.
*/
int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count)
{
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
/* Ensure that the number of VFs allocated is non-zero and
* is not greater than the number of supported VFs defined in
* the functional capabilities of the PF.
*/
if (!vf_count || vf_count > hw->func_caps.num_allocd_vfs)
return -EINVAL;
snap->mbx_vf.vf_cntr = devm_kcalloc(ice_hw_to_dev(hw), vf_count,
sizeof(*snap->mbx_vf.vf_cntr),
GFP_KERNEL);
if (!snap->mbx_vf.vf_cntr)
return -ENOMEM;
/* Setting the VF counter length to the number of allocated
* VFs for given PF's functional capabilities.
*/
snap->mbx_vf.vfcntr_len = vf_count;
/* Clear mbx_buf in the mailbox snaphot structure and setting the
* mailbox snapshot state to a new capture.
*/
memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
return 0;
}
/**
* ice_mbx_deinit_snapshot - Free mailbox snapshot structure
* @hw: pointer to the hardware structure
*
* Clear the mailbox snapshot structure and free the VF counter array.
*/
void ice_mbx_deinit_snapshot(struct ice_hw *hw)
{
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
/* Free VF counter array and reset VF counter length */
devm_kfree(ice_hw_to_dev(hw), snap->mbx_vf.vf_cntr);
snap->mbx_vf.vfcntr_len = 0;
/* Clear mbx_buf in the mailbox snaphot structure */
memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
}
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018, Intel Corporation. */
#ifndef _ICE_VF_MBX_H_
#define _ICE_VF_MBX_H_
#include "ice_type.h"
#include "ice_controlq.h"
/* Defining the mailbox message threshold as 63 asynchronous
* pending messages. Normal VF functionality does not require
* sending more than 63 asynchronous pending message.
*/
#define ICE_ASYNC_VF_MSG_THRESHOLD 63
#ifdef CONFIG_PCI_IOV
int
ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
u8 *msg, u16 msglen, struct ice_sq_cd *cd);
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
int
ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
u16 vf_id, bool *is_mal_vf);
int
ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id);
int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count);
void ice_mbx_deinit_snapshot(struct ice_hw *hw);
int
ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
u16 bitmap_len, u16 vf_id, bool *report_malvf);
#else /* CONFIG_PCI_IOV */
static inline int
ice_aq_send_msg_to_vf(struct ice_hw __always_unused *hw,
u16 __always_unused vfid, u32 __always_unused v_opcode,
u32 __always_unused v_retval, u8 __always_unused *msg,
u16 __always_unused msglen,
struct ice_sq_cd __always_unused *cd)
{
return 0;
}
static inline u32
ice_conv_link_speed_to_virtchnl(bool __always_unused adv_link_support,
u16 __always_unused link_speed)
{
return 0;
}
#endif /* CONFIG_PCI_IOV */
#endif /* _ICE_VF_MBX_H_ */
......@@ -6,7 +6,7 @@
#include "ice_vlan_mode.h"
#include "ice.h"
#include "ice_vf_vsi_vlan_ops.h"
#include "ice_virtchnl_pf.h"
#include "ice_sriov.h"
static int
noop_vlan_arg(struct ice_vsi __always_unused *vsi,
......
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018, Intel Corporation. */
#ifndef _ICE_VIRTCHNL_PF_H_
#define _ICE_VIRTCHNL_PF_H_
#include "ice.h"
#include "ice_virtchnl_fdir.h"
#include "ice_vsi_vlan_ops.h"
/* Restrict number of MAC Addr and VLAN that non-trusted VF can programmed */
#define ICE_MAX_VLAN_PER_VF 8
/* MAC filters: 1 is reserved for the VF's default/perm_addr/LAA MAC, 1 for
* broadcast, and 16 for additional unicast/multicast filters
*/
#define ICE_MAX_MACADDR_PER_VF 18
/* Malicious Driver Detection */
#define ICE_MDD_EVENTS_THRESHOLD 30
/* Static VF transaction/status register def */
#define VF_DEVICE_STATUS 0xAA
#define VF_TRANS_PENDING_M 0x20
/* wait defines for polling PF_PCI_CIAD register status */
#define ICE_PCI_CIAD_WAIT_COUNT 100
#define ICE_PCI_CIAD_WAIT_DELAY_US 1
/* VF resource constraints */
#define ICE_MAX_VF_COUNT 256
#define ICE_MIN_QS_PER_VF 1
#define ICE_NONQ_VECS_VF 1
#define ICE_MAX_SCATTER_QS_PER_VF 16
#define ICE_MAX_RSS_QS_PER_VF 16
#define ICE_NUM_VF_MSIX_MED 17
#define ICE_NUM_VF_MSIX_SMALL 5
#define ICE_NUM_VF_MSIX_MULTIQ_MIN 3
#define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1)
#define ICE_MAX_VF_RESET_TRIES 40
#define ICE_MAX_VF_RESET_SLEEP_MS 20
/* VF Hash Table access functions
*
* These functions provide abstraction for interacting with the VF hash table.
* In general, direct access to the hash table should be avoided outside of
* these functions where possible.
*
* The VF entries in the hash table are protected by reference counting to
* track lifetime of accesses from the table. The ice_get_vf_by_id() function
* obtains a reference to the VF structure which must be dropped by using
* ice_put_vf().
*/
/**
* ice_for_each_vf - Iterate over each VF entry
* @pf: pointer to the PF private structure
* @bkt: bucket index used for iteration
* @vf: pointer to the VF entry currently being processed in the loop.
*
* The bkt variable is an unsigned integer iterator used to traverse the VF
* entries. It is *not* guaranteed to be the VF's vf_id. Do not assume it is.
* Use vf->vf_id to get the id number if needed.
*
* The caller is expected to be under the table_lock mutex for the entire
* loop. Use this iterator if your loop is long or if it might sleep.
*/
#define ice_for_each_vf(pf, bkt, vf) \
hash_for_each((pf)->vfs.table, (bkt), (vf), entry)
/**
* ice_for_each_vf_rcu - Iterate over each VF entry protected by RCU
* @pf: pointer to the PF private structure
* @bkt: bucket index used for iteration
* @vf: pointer to the VF entry currently being processed in the loop.
*
* The bkt variable is an unsigned integer iterator used to traverse the VF
* entries. It is *not* guaranteed to be the VF's vf_id. Do not assume it is.
* Use vf->vf_id to get the id number if needed.
*
* The caller is expected to be under rcu_read_lock() for the entire loop.
* Only use this iterator if your loop is short and you can guarantee it does
* not sleep.
*/
#define ice_for_each_vf_rcu(pf, bkt, vf) \
hash_for_each_rcu((pf)->vfs.table, (bkt), (vf), entry)
/* Specific VF states */
enum ice_vf_states {
ICE_VF_STATE_INIT = 0, /* PF is initializing VF */
ICE_VF_STATE_ACTIVE, /* VF resources are allocated for use */
ICE_VF_STATE_QS_ENA, /* VF queue(s) enabled */
ICE_VF_STATE_DIS,
ICE_VF_STATE_MC_PROMISC,
ICE_VF_STATE_UC_PROMISC,
ICE_VF_STATES_NBITS
};
/* VF capabilities */
enum ice_virtchnl_cap {
ICE_VIRTCHNL_VF_CAP_L2 = 0,
ICE_VIRTCHNL_VF_CAP_PRIVILEGE,
};
struct ice_time_mac {
unsigned long time_modified;
u8 addr[ETH_ALEN];
};
/* VF MDD events print structure */
struct ice_mdd_vf_events {
u16 count; /* total count of Rx|Tx events */
/* count number of the last printed event */
u16 last_printed;
};
struct ice_vf;
struct ice_vc_vf_ops {
int (*get_ver_msg)(struct ice_vf *vf, u8 *msg);
int (*get_vf_res_msg)(struct ice_vf *vf, u8 *msg);
void (*reset_vf)(struct ice_vf *vf);
int (*add_mac_addr_msg)(struct ice_vf *vf, u8 *msg);
int (*del_mac_addr_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*request_qs_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_irq_map_msg)(struct ice_vf *vf, u8 *msg);
int (*config_rss_key)(struct ice_vf *vf, u8 *msg);
int (*config_rss_lut)(struct ice_vf *vf, u8 *msg);
int (*get_stats_msg)(struct ice_vf *vf, u8 *msg);
int (*cfg_promiscuous_mode_msg)(struct ice_vf *vf, u8 *msg);
int (*add_vlan_msg)(struct ice_vf *vf, u8 *msg);
int (*remove_vlan_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_stripping)(struct ice_vf *vf);
int (*dis_vlan_stripping)(struct ice_vf *vf);
int (*handle_rss_cfg_msg)(struct ice_vf *vf, u8 *msg, bool add);
int (*add_fdir_fltr_msg)(struct ice_vf *vf, u8 *msg);
int (*del_fdir_fltr_msg)(struct ice_vf *vf, u8 *msg);
int (*get_offload_vlan_v2_caps)(struct ice_vf *vf);
int (*add_vlan_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*remove_vlan_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_stripping_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_vlan_stripping_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*ena_vlan_insertion_v2_msg)(struct ice_vf *vf, u8 *msg);
int (*dis_vlan_insertion_v2_msg)(struct ice_vf *vf, u8 *msg);
};
/* Virtchnl/SR-IOV config info */
struct ice_vfs {
DECLARE_HASHTABLE(table, 8); /* table of VF entries */
struct mutex table_lock; /* Lock for protecting the hash table */
u16 num_supported; /* max supported VFs on this PF */
u16 num_qps_per; /* number of queue pairs per VF */
u16 num_msix_per; /* number of MSI-X vectors per VF */
unsigned long last_printed_mdd_jiffies; /* MDD message rate limit */
DECLARE_BITMAP(malvfs, ICE_MAX_VF_COUNT); /* malicious VF indicator */
};
/* VF information structure */
struct ice_vf {
struct hlist_node entry;
struct rcu_head rcu;
struct kref refcnt;
struct ice_pf *pf;
/* Used during virtchnl message handling and NDO ops against the VF
* that will trigger a VFR
*/
struct mutex cfg_lock;
u16 vf_id; /* VF ID in the PF space */
u16 lan_vsi_idx; /* index into PF struct */
u16 ctrl_vsi_idx;
struct ice_vf_fdir fdir;
/* first vector index of this VF in the PF space */
int first_vector_idx;
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;
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);
struct ice_vlan port_vlan_info; /* Port VLAN ID, QoS, and TPID */
struct virtchnl_vlan_caps vlan_v2_caps;
u8 pf_set_mac:1; /* VF MAC address set by VMM admin */
u8 trusted:1;
u8 spoofchk:1;
u8 link_forced:1;
u8 link_up:1; /* only valid if VF link is forced */
/* VSI indices - actual VSI pointers are maintained in the PF structure
* When assigned, these will be non-zero, because VSI 0 is always
* the main LAN VSI for the PF.
*/
u16 lan_vsi_num; /* ID as used by firmware */
unsigned int min_tx_rate; /* Minimum Tx bandwidth limit in Mbps */
unsigned int max_tx_rate; /* Maximum Tx bandwidth limit in Mbps */
DECLARE_BITMAP(vf_states, ICE_VF_STATES_NBITS); /* VF runtime states */
unsigned long vf_caps; /* VF's adv. capabilities */
u8 num_req_qs; /* num of queue pairs requested by VF */
u16 num_mac;
u16 num_vf_qs; /* num of queue configured per VF */
struct ice_mdd_vf_events mdd_rx_events;
struct ice_mdd_vf_events mdd_tx_events;
DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
struct ice_repr *repr;
struct ice_vc_vf_ops vc_ops;
/* devlink port data */
struct devlink_port devlink_port;
};
#ifdef CONFIG_PCI_IOV
struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id);
void ice_put_vf(struct ice_vf *vf);
bool ice_has_vfs(struct ice_pf *pf);
u16 ice_get_num_vfs(struct ice_pf *pf);
struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf);
void ice_process_vflr_event(struct ice_pf *pf);
int ice_sriov_configure(struct pci_dev *pdev, int num_vfs);
int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
int
ice_get_vf_cfg(struct net_device *netdev, int vf_id, struct ifla_vf_info *ivi);
void ice_free_vfs(struct ice_pf *pf);
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event);
void ice_vc_notify_link_state(struct ice_pf *pf);
void ice_vc_notify_reset(struct ice_pf *pf);
void ice_vc_notify_vf_link_state(struct ice_vf *vf);
void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops);
void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops);
bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr);
bool ice_reset_vf(struct ice_vf *vf, bool is_vflr);
void ice_restore_all_vfs_msi_state(struct pci_dev *pdev);
bool
ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event,
u16 num_msg_proc, u16 num_msg_pending);
int
ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
__be16 vlan_proto);
int
ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
int max_tx_rate);
int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted);
int ice_set_vf_link_state(struct net_device *netdev, int vf_id, int link_state);
int ice_check_vf_ready_for_cfg(struct ice_vf *vf);
bool ice_is_vf_disabled(struct ice_vf *vf);
int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena);
int ice_calc_vf_reg_idx(struct ice_vf *vf, struct ice_q_vector *q_vector);
void ice_set_vf_state_qs_dis(struct ice_vf *vf);
int
ice_get_vf_stats(struct net_device *netdev, int vf_id,
struct ifla_vf_stats *vf_stats);
bool ice_is_any_vf_in_promisc(struct ice_pf *pf);
void
ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event);
void ice_print_vfs_mdd_events(struct ice_pf *pf);
void ice_print_vf_rx_mdd_event(struct ice_vf *vf);
bool
ice_vc_validate_pattern(struct ice_vf *vf, struct virtchnl_proto_hdrs *proto);
struct ice_vsi *ice_vf_ctrl_vsi_setup(struct ice_vf *vf);
int
ice_vc_send_msg_to_vf(struct ice_vf *vf, u32 v_opcode,
enum virtchnl_status_code v_retval, u8 *msg, u16 msglen);
bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id);
bool ice_vf_is_port_vlan_ena(struct ice_vf *vf);
#else /* CONFIG_PCI_IOV */
static inline struct ice_vf *ice_get_vf_by_id(struct ice_pf *pf, u16 vf_id)
{
return NULL;
}
static inline void ice_put_vf(struct ice_vf *vf)
{
}
static inline bool ice_has_vfs(struct ice_pf *pf)
{
return false;
}
static inline u16 ice_get_num_vfs(struct ice_pf *pf)
{
return 0;
}
static inline void ice_process_vflr_event(struct ice_pf *pf) { }
static inline void ice_free_vfs(struct ice_pf *pf) { }
static inline
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) { }
static inline void ice_vc_notify_link_state(struct ice_pf *pf) { }
static inline void ice_vc_notify_reset(struct ice_pf *pf) { }
static inline void ice_vc_notify_vf_link_state(struct ice_vf *vf) { }
static inline void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops) { }
static inline void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops) { }
static inline void ice_set_vf_state_qs_dis(struct ice_vf *vf) { }
static inline
void ice_vf_lan_overflow_event(struct ice_pf *pf, struct ice_rq_event_info *event) { }
static inline void ice_print_vfs_mdd_events(struct ice_pf *pf) { }
static inline void ice_print_vf_rx_mdd_event(struct ice_vf *vf) { }
static inline void ice_restore_all_vfs_msi_state(struct pci_dev *pdev) { }
static inline int ice_check_vf_ready_for_cfg(struct ice_vf *vf)
{
return -EOPNOTSUPP;
}
static inline bool ice_is_vf_disabled(struct ice_vf *vf)
{
return true;
}
static inline struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf)
{
return NULL;
}
static inline bool
ice_is_malicious_vf(struct ice_pf __always_unused *pf,
struct ice_rq_event_info __always_unused *event,
u16 __always_unused num_msg_proc,
u16 __always_unused num_msg_pending)
{
return false;
}
static inline bool
ice_reset_all_vfs(struct ice_pf __always_unused *pf,
bool __always_unused is_vflr)
{
return true;
}
static inline bool
ice_reset_vf(struct ice_vf __always_unused *vf, bool __always_unused is_vflr)
{
return true;
}
static inline int
ice_sriov_configure(struct pci_dev __always_unused *pdev,
int __always_unused num_vfs)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_mac(struct net_device __always_unused *netdev,
int __always_unused vf_id, u8 __always_unused *mac)
{
return -EOPNOTSUPP;
}
static inline int
ice_get_vf_cfg(struct net_device __always_unused *netdev,
int __always_unused vf_id,
struct ifla_vf_info __always_unused *ivi)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_trust(struct net_device __always_unused *netdev,
int __always_unused vf_id, bool __always_unused trusted)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_port_vlan(struct net_device __always_unused *netdev,
int __always_unused vf_id, u16 __always_unused vid,
u8 __always_unused qos, __be16 __always_unused v_proto)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_spoofchk(struct net_device __always_unused *netdev,
int __always_unused vf_id, bool __always_unused ena)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_link_state(struct net_device __always_unused *netdev,
int __always_unused vf_id, int __always_unused link_state)
{
return -EOPNOTSUPP;
}
static inline int
ice_set_vf_bw(struct net_device __always_unused *netdev,
int __always_unused vf_id, int __always_unused min_tx_rate,
int __always_unused max_tx_rate)
{
return -EOPNOTSUPP;
}
static inline int
ice_calc_vf_reg_idx(struct ice_vf __always_unused *vf,
struct ice_q_vector __always_unused *q_vector)
{
return 0;
}
static inline int
ice_get_vf_stats(struct net_device __always_unused *netdev,
int __always_unused vf_id,
struct ifla_vf_stats __always_unused *vf_stats)
{
return -EOPNOTSUPP;
}
static inline bool ice_is_any_vf_in_promisc(struct ice_pf __always_unused *pf)
{
return false;
}
static inline bool ice_vf_is_port_vlan_ena(struct ice_vf __always_unused *vf)
{
return false;
}
#endif /* CONFIG_PCI_IOV */
#endif /* _ICE_VIRTCHNL_PF_H_ */
......@@ -4,7 +4,6 @@
#ifndef _ICE_XSK_H_
#define _ICE_XSK_H_
#include "ice_txrx.h"
#include "ice.h"
#define PKTS_PER_BATCH 8
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册