mirror of
https://github.com/opnsense/src.git
synced 2026-06-13 18:50:31 -04:00
ice: Add host SR-IOV support
Enable basic SR-IOV support for E800 adapters. Authored-by: Eric Joyner <erj@FreeBSD.org> Signed-off-by: Krzysztof Galazka <krzysztof.galazka@intel.com> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1573
This commit is contained in:
parent
7986051313
commit
bc761988b7
11 changed files with 2549 additions and 0 deletions
|
|
@ -191,6 +191,10 @@ dev/ice/irdma_di_if.m optional ice pci \
|
|||
compile-with "${NORMAL_M} -I$S/dev/ice"
|
||||
dev/ice/ice_ddp_common.c optional ice pci \
|
||||
compile-with "${NORMAL_C} -I$S/dev/ice"
|
||||
dev/ice/ice_iov.c optional ice pci pci_iov \
|
||||
compile-with "${NORMAL_C} -I$S/dev/ice"
|
||||
dev/ice/ice_vf_mbx.c optional ice pci pci_iov \
|
||||
compile-with "${NORMAL_C} -I$S/dev/ice"
|
||||
ice_ddp.c optional ice_ddp \
|
||||
compile-with "${AWK} -f $S/tools/fw_stub.awk ice_ddp.fw:ice_ddp:0x01032900 -mice_ddp -c${.TARGET}" \
|
||||
no-ctfconvert no-implicit-rule before-depend local \
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ enum feat_list {
|
|||
static inline void
|
||||
ice_disable_unsupported_features(ice_bitmap_t __unused *bitmap)
|
||||
{
|
||||
#ifndef PCI_IOV
|
||||
ice_clear_bit(ICE_FEATURE_SRIOV, bitmap);
|
||||
#endif
|
||||
#ifndef DEV_NETMAP
|
||||
ice_clear_bit(ICE_FEATURE_NETMAP, bitmap);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -139,6 +139,9 @@ struct ice_irq_vector {
|
|||
* @tc: traffic class queue belongs to
|
||||
* @q_handle: qidx in tc; used in TXQ enable functions
|
||||
*
|
||||
* ice_iov.c requires the following parameters (when PCI_IOV is defined):
|
||||
* @itr_idx: ITR index to use for this queue
|
||||
*
|
||||
* Other parameters may be iflib driver specific
|
||||
*/
|
||||
struct ice_tx_queue {
|
||||
|
|
@ -153,6 +156,9 @@ struct ice_tx_queue {
|
|||
u32 me;
|
||||
u16 q_handle;
|
||||
u8 tc;
|
||||
#ifdef PCI_IOV
|
||||
u8 itr_idx;
|
||||
#endif
|
||||
|
||||
/* descriptor writeback status */
|
||||
qidx_t *tx_rsq;
|
||||
|
|
@ -175,6 +181,9 @@ struct ice_tx_queue {
|
|||
* @stats: queue statistics
|
||||
* @tc: traffic class queue belongs to
|
||||
*
|
||||
* ice_iov.c requires the following parameters (when PCI_IOV is defined):
|
||||
* @itr_idx: ITR index to use for this queue
|
||||
*
|
||||
* Other parameters may be iflib driver specific
|
||||
*/
|
||||
struct ice_rx_queue {
|
||||
|
|
@ -187,6 +196,9 @@ struct ice_rx_queue {
|
|||
struct ice_irq_vector *irqv;
|
||||
u32 me;
|
||||
u8 tc;
|
||||
#ifdef PCI_IOV
|
||||
u8 itr_idx;
|
||||
#endif
|
||||
|
||||
struct if_irq que_irq;
|
||||
};
|
||||
|
|
@ -332,6 +344,10 @@ struct ice_softc {
|
|||
ice_declare_bitmap(feat_cap, ICE_FEATURE_COUNT);
|
||||
ice_declare_bitmap(feat_en, ICE_FEATURE_COUNT);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
struct ice_vf *vfs;
|
||||
u16 num_vfs;
|
||||
#endif
|
||||
struct ice_resmgr os_imgr;
|
||||
/* For mirror interface */
|
||||
struct ice_mirr_if *mirr_if;
|
||||
|
|
|
|||
1732
sys/dev/ice/ice_iov.c
Normal file
1732
sys/dev/ice/ice_iov.c
Normal file
File diff suppressed because it is too large
Load diff
115
sys/dev/ice/ice_iov.h
Normal file
115
sys/dev/ice/ice_iov.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/* Copyright (c) 2025, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ice_iov.h
|
||||
* @brief header for IOV functionality
|
||||
*
|
||||
* This header includes definitions used to implement device Virtual Functions
|
||||
* for the ice driver.
|
||||
*/
|
||||
|
||||
#ifndef _ICE_IOV_H_
|
||||
#define _ICE_IOV_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/nv.h>
|
||||
#include <sys/iov_schema.h>
|
||||
#include <sys/param.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <dev/pci/pci_iov.h>
|
||||
|
||||
#include "ice_iflib.h"
|
||||
#include "ice_vf_mbx.h"
|
||||
|
||||
/**
|
||||
* @enum ice_vf_flags
|
||||
* @brief VF state flags
|
||||
*
|
||||
* Used to indicate the status of a PF's VF, as well as indicating what each VF
|
||||
* is capabile of. Intended to be modified only using atomic operations, so
|
||||
* they can be read and modified in places that aren't locked.
|
||||
*
|
||||
* Used in struct ice_vf's vf_flags field.
|
||||
*/
|
||||
enum ice_vf_flags {
|
||||
VF_FLAG_ENABLED = BIT(0),
|
||||
VF_FLAG_SET_MAC_CAP = BIT(1),
|
||||
VF_FLAG_VLAN_CAP = BIT(2),
|
||||
VF_FLAG_PROMISC_CAP = BIT(3),
|
||||
VF_FLAG_MAC_ANTI_SPOOF = BIT(4),
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct ice_vf
|
||||
* @brief PF's VF software context
|
||||
*
|
||||
* Represents the state and options for a VF spawned from a PF.
|
||||
*/
|
||||
struct ice_vf {
|
||||
struct ice_vsi *vsi;
|
||||
u32 vf_flags;
|
||||
|
||||
u8 mac[ETHER_ADDR_LEN];
|
||||
u16 vf_num;
|
||||
struct virtchnl_version_info version;
|
||||
|
||||
u16 num_irq_vectors;
|
||||
u16 *vf_imap;
|
||||
struct ice_irq_vector *tx_irqvs;
|
||||
struct ice_irq_vector *rx_irqvs;
|
||||
};
|
||||
|
||||
#define ICE_PCIE_DEV_STATUS 0xAA
|
||||
|
||||
#define ICE_PCI_CIAD_WAIT_COUNT 100
|
||||
#define ICE_PCI_CIAD_WAIT_DELAY_US 1
|
||||
#define ICE_VPGEN_VFRSTAT_WAIT_COUNT 100
|
||||
#define ICE_VPGEN_VFRSTAT_WAIT_DELAY_US 20
|
||||
|
||||
#define ICE_VIRTCHNL_VALID_PROMISC_FLAGS (FLAG_VF_UNICAST_PROMISC | \
|
||||
FLAG_VF_MULTICAST_PROMISC)
|
||||
|
||||
int ice_iov_attach(struct ice_softc *sc);
|
||||
int ice_iov_detach(struct ice_softc *sc);
|
||||
|
||||
int ice_iov_init(struct ice_softc *sc, uint16_t num_vfs, const nvlist_t *params);
|
||||
int ice_iov_add_vf(struct ice_softc *sc, uint16_t vfnum, const nvlist_t *params);
|
||||
void ice_iov_uninit(struct ice_softc *sc);
|
||||
|
||||
void ice_vc_handle_vf_msg(struct ice_softc *sc, struct ice_rq_event_info *event);
|
||||
void ice_vc_notify_all_vfs_link_state(struct ice_softc *sc);
|
||||
|
||||
#endif /* _ICE_IOV_H_ */
|
||||
|
||||
|
|
@ -42,6 +42,9 @@
|
|||
|
||||
#include "ice_lib.h"
|
||||
#include "ice_iflib.h"
|
||||
#ifdef PCI_IOV
|
||||
#include "ice_iov.h"
|
||||
#endif
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <machine/resource.h>
|
||||
|
|
@ -741,6 +744,12 @@ ice_initialize_vsi(struct ice_vsi *vsi)
|
|||
case ICE_VSI_VMDQ2:
|
||||
ctx.flags = ICE_AQ_VSI_TYPE_VMDQ2;
|
||||
break;
|
||||
#ifdef PCI_IOV
|
||||
case ICE_VSI_VF:
|
||||
ctx.flags = ICE_AQ_VSI_TYPE_VF;
|
||||
ctx.vf_num = vsi->vf_num;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return (ENODEV);
|
||||
}
|
||||
|
|
@ -1607,6 +1616,12 @@ ice_setup_tx_ctx(struct ice_tx_queue *txq, struct ice_tlan_ctx *tlan_ctx, u16 pf
|
|||
case ICE_VSI_VMDQ2:
|
||||
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_VMQ;
|
||||
break;
|
||||
#ifdef PCI_IOV
|
||||
case ICE_VSI_VF:
|
||||
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_VF;
|
||||
tlan_ctx->vmvf_num = hw->func_caps.vf_base_id + vsi->vf_num;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return (ENODEV);
|
||||
}
|
||||
|
|
@ -2257,6 +2272,11 @@ ice_process_ctrlq_event(struct ice_softc *sc, const char *qname,
|
|||
case ice_aqc_opc_get_link_status:
|
||||
ice_process_link_event(sc, event);
|
||||
break;
|
||||
#ifdef PCI_IOV
|
||||
case ice_mbx_opc_send_msg_to_pf:
|
||||
ice_vc_handle_vf_msg(sc, event);
|
||||
break;
|
||||
#endif
|
||||
case ice_aqc_opc_fw_logs_event:
|
||||
ice_handle_fw_log_event(sc, &event->desc, event->msg_buf);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -611,6 +611,10 @@ struct ice_vsi {
|
|||
u16 mirror_src_vsi;
|
||||
u16 rule_mir_ingress;
|
||||
u16 rule_mir_egress;
|
||||
|
||||
#ifdef PCI_IOV
|
||||
u8 vf_num; /* Index of owning VF, if applicable */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
471
sys/dev/ice/ice_vf_mbx.c
Normal file
471
sys/dev/ice/ice_vf_mbx.c
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/* Copyright (c) 2025, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ice_common.h"
|
||||
#include "ice_hw_autogen.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_aq_send_msg_to_pf
|
||||
* @hw: pointer to the hardware structure
|
||||
* @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 PF driver using mailbox queue. By default, this
|
||||
* message is sent asynchronously, i.e. ice_sq_send_cmd()
|
||||
* does not wait for completion before returning.
|
||||
*/
|
||||
int
|
||||
ice_aq_send_msg_to_pf(struct ice_hw *hw, enum virtchnl_ops v_opcode,
|
||||
int v_retval, u8 *msg, u16 msglen,
|
||||
struct ice_sq_cd *cd)
|
||||
{
|
||||
struct ice_aq_desc desc;
|
||||
|
||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_mbx_opc_send_msg_to_pf);
|
||||
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);
|
||||
}
|
||||
|
||||
static const u32 ice_legacy_aq_to_vc_speed[] = {
|
||||
VIRTCHNL_LINK_SPEED_100MB, /* BIT(0) */
|
||||
VIRTCHNL_LINK_SPEED_100MB,
|
||||
VIRTCHNL_LINK_SPEED_1GB,
|
||||
VIRTCHNL_LINK_SPEED_1GB,
|
||||
VIRTCHNL_LINK_SPEED_1GB,
|
||||
VIRTCHNL_LINK_SPEED_10GB,
|
||||
VIRTCHNL_LINK_SPEED_20GB,
|
||||
VIRTCHNL_LINK_SPEED_25GB,
|
||||
VIRTCHNL_LINK_SPEED_40GB,
|
||||
VIRTCHNL_LINK_SPEED_40GB,
|
||||
VIRTCHNL_LINK_SPEED_40GB,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
/* convert a BIT() value into an array index */
|
||||
u16 index = (u16)(ice_fls(link_speed) - 1);
|
||||
|
||||
if (adv_link_support)
|
||||
return ice_get_link_speed(index);
|
||||
else if (index < ARRAY_SIZE(ice_legacy_aq_to_vc_speed))
|
||||
/* 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
|
||||
*/
|
||||
return ice_legacy_aq_to_vc_speed[index];
|
||||
|
||||
return VIRTCHNL_LINK_SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* requires calling ice_mbx_reset_snapshot() as well as calling
|
||||
* ice_mbx_reset_vf_info() for each VF tracking structure.
|
||||
*
|
||||
* 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 tracking structure
|
||||
* for the VF must be passed to the state handler. The boolean output
|
||||
* report_malvf from ice_mbx_vf_state_handler() serves as an indicator to the
|
||||
* caller whether it must report this VF as malicious or not.
|
||||
*
|
||||
* 5. When a VF is identified to be malicious, the caller can send a message
|
||||
* to the system administrator.
|
||||
*
|
||||
* 6. The PF is responsible for maintaining the struct ice_mbx_vf_info
|
||||
* structure for each VF. The PF should clear the VF tracking structure if the
|
||||
* VF is reset. When a VF is shut down and brought back up, we will then
|
||||
* assume that the new VF is not malicious and may report it again if we
|
||||
* detect it again.
|
||||
*
|
||||
* 7. The function ice_mbx_reset_snapshot() is called to reset the information
|
||||
* in ice_mbx_snapshot for every new mailbox interrupt handled.
|
||||
*/
|
||||
#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_reset_snapshot - Initialize mailbox snapshot structure
|
||||
* @snap: pointer to the mailbox snapshot
|
||||
*/
|
||||
static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap)
|
||||
{
|
||||
struct ice_mbx_vf_info *vf_info;
|
||||
|
||||
/* Clear mbx_buf in the mailbox snaphot structure and setting the
|
||||
* mailbox snapshot state to a new capture.
|
||||
*/
|
||||
ice_memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf), ICE_NONDMA_MEM);
|
||||
snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
|
||||
|
||||
/* Reset message counts for all VFs to zero */
|
||||
LIST_FOR_EACH_ENTRY(vf_info, &snap->mbx_vf, ice_mbx_vf_info, list_entry)
|
||||
vf_info->msg_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_info: mailbox tracking structure for a VF
|
||||
* @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, struct ice_mbx_vf_info *vf_info,
|
||||
enum ice_mbx_snapshot_state *new_state,
|
||||
bool *is_malvf)
|
||||
{
|
||||
/* increment the message count for this VF */
|
||||
vf_info->msg_count++;
|
||||
|
||||
if (vf_info->msg_count >= ICE_ASYNC_VF_MSG_THRESHOLD)
|
||||
*is_malvf = true;
|
||||
|
||||
/* continue to iterate through the mailbox snapshot */
|
||||
ice_mbx_traverse(hw, new_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_e830_mbx_vf_dec_trig - Decrements the VF mailbox queue counter
|
||||
* @hw: pointer to the HW struct
|
||||
* @event: pointer to the control queue receive event
|
||||
*
|
||||
* This function triggers to decrement the counter
|
||||
* MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes
|
||||
* the buffers at the PF mailbox queue.
|
||||
*/
|
||||
void ice_e830_mbx_vf_dec_trig(struct ice_hw *hw,
|
||||
struct ice_rq_event_info *event)
|
||||
{
|
||||
u16 vfid = LE16_TO_CPU(event->desc.retval);
|
||||
|
||||
wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count
|
||||
* @hw: pointer to the HW struct
|
||||
* @vf_id: VF ID in the PF space
|
||||
*
|
||||
* This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT, and should
|
||||
* be called when a VF is created and on VF reset.
|
||||
*/
|
||||
void ice_mbx_vf_clear_cnt_e830(struct ice_hw *hw, u16 vf_id)
|
||||
{
|
||||
u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id));
|
||||
|
||||
wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_info: mailbox tracking structure for the VF in question
|
||||
* @report_malvf: boolean output to indicate whether VF should be reported
|
||||
*
|
||||
* 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,
|
||||
struct ice_mbx_vf_info *vf_info, bool *report_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;
|
||||
bool is_malvf = false;
|
||||
|
||||
if (!report_malvf || !mbx_data || !vf_info)
|
||||
return ICE_ERR_BAD_PTR;
|
||||
|
||||
*report_malvf = false;
|
||||
|
||||
/* When entering the mailbox state machine assume that the VF
|
||||
* is not malicious until detected.
|
||||
*/
|
||||
/* 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 ICE_ERR_INVAL_SIZE;
|
||||
|
||||
/* 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 ICE_ERR_PARAM;
|
||||
|
||||
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_info, &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_info, &new_state, &is_malvf);
|
||||
break;
|
||||
|
||||
default:
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
|
||||
status = ICE_ERR_CFG;
|
||||
}
|
||||
|
||||
snap_buf->state = new_state;
|
||||
|
||||
/* Only report VFs as malicious the first time we detect it */
|
||||
if (is_malvf && !vf_info->malicious) {
|
||||
vf_info->malicious = 1;
|
||||
*report_malvf = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_clear_malvf - Clear VF mailbox info
|
||||
* @vf_info: the mailbox tracking structure for a VF
|
||||
*
|
||||
* In case of a VF reset, this function shall be called to clear the VF's
|
||||
* current mailbox tracking state.
|
||||
*/
|
||||
void ice_mbx_clear_malvf(struct ice_mbx_vf_info *vf_info)
|
||||
{
|
||||
vf_info->malicious = 0;
|
||||
vf_info->msg_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_init_vf_info - Initialize a new VF mailbox tracking info
|
||||
* @hw: pointer to the hardware structure
|
||||
* @vf_info: the mailbox tracking info structure for a VF
|
||||
*
|
||||
* Initialize a VF mailbox tracking info structure and insert it into the
|
||||
* snapshot list.
|
||||
*
|
||||
* If you remove the VF, you must also delete the associated VF info structure
|
||||
* from the linked list.
|
||||
*/
|
||||
void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
|
||||
ice_mbx_clear_malvf(vf_info);
|
||||
LIST_ADD(&vf_info->list_entry, &snap->mbx_vf);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_init_snapshot - Initialize mailbox snapshot data
|
||||
* @hw: pointer to the hardware structure
|
||||
*
|
||||
* Clear the mailbox snapshot structure and initialize the VF mailbox list.
|
||||
*/
|
||||
void ice_mbx_init_snapshot(struct ice_hw *hw)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
|
||||
INIT_LIST_HEAD(&snap->mbx_vf);
|
||||
ice_mbx_reset_snapshot(snap);
|
||||
}
|
||||
67
sys/dev/ice/ice_vf_mbx.h
Normal file
67
sys/dev/ice/ice_vf_mbx.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/* Copyright (c) 2025, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
/* Threshold value should be used to initialize
|
||||
* MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT register.
|
||||
*/
|
||||
#define ICE_ASYNC_VF_MSG_THRESHOLD 63
|
||||
|
||||
int
|
||||
ice_aq_send_msg_to_pf(struct ice_hw *hw, enum virtchnl_ops v_opcode,
|
||||
int v_retval, u8 *msg, u16 msglen,
|
||||
struct ice_sq_cd *cd);
|
||||
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);
|
||||
|
||||
void ice_e830_mbx_vf_dec_trig(struct ice_hw *hw,
|
||||
struct ice_rq_event_info *event);
|
||||
void ice_mbx_vf_clear_cnt_e830(struct ice_hw *hw, u16 vf_id);
|
||||
int
|
||||
ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
|
||||
struct ice_mbx_vf_info *vf_info, bool *report_malvf);
|
||||
void ice_mbx_clear_malvf(struct ice_mbx_vf_info *vf_info);
|
||||
void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info);
|
||||
void ice_mbx_init_snapshot(struct ice_hw *hw);
|
||||
#endif /* _ICE_VF_MBX_H_ */
|
||||
|
|
@ -42,6 +42,9 @@
|
|||
#include "ice_drv_info.h"
|
||||
#include "ice_switch.h"
|
||||
#include "ice_sched.h"
|
||||
#ifdef PCI_IOV
|
||||
#include "ice_iov.h"
|
||||
#endif
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/sockio.h>
|
||||
|
|
@ -85,6 +88,12 @@ static int ice_if_suspend(if_ctx_t ctx);
|
|||
static int ice_if_resume(if_ctx_t ctx);
|
||||
static bool ice_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event);
|
||||
static void ice_init_link(struct ice_softc *sc);
|
||||
#ifdef PCI_IOV
|
||||
static int ice_if_iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params);
|
||||
static void ice_if_iov_uninit(if_ctx_t ctx);
|
||||
static int ice_if_iov_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params);
|
||||
static void ice_if_vflr_handle(if_ctx_t ctx);
|
||||
#endif
|
||||
static int ice_setup_mirror_vsi(struct ice_mirr_if *mif);
|
||||
static int ice_wire_mirror_intrs(struct ice_mirr_if *mif);
|
||||
static void ice_free_irqvs_subif(struct ice_mirr_if *mif);
|
||||
|
|
@ -158,6 +167,11 @@ static device_method_t ice_methods[] = {
|
|||
DEVMETHOD(device_shutdown, iflib_device_shutdown),
|
||||
DEVMETHOD(device_suspend, iflib_device_suspend),
|
||||
DEVMETHOD(device_resume, iflib_device_resume),
|
||||
#ifdef PCI_IOV
|
||||
DEVMETHOD(pci_iov_init, iflib_device_iov_init),
|
||||
DEVMETHOD(pci_iov_uninit, iflib_device_iov_uninit),
|
||||
DEVMETHOD(pci_iov_add_vf, iflib_device_iov_add_vf),
|
||||
#endif
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
|
@ -198,6 +212,12 @@ static device_method_t ice_iflib_methods[] = {
|
|||
DEVMETHOD(ifdi_suspend, ice_if_suspend),
|
||||
DEVMETHOD(ifdi_resume, ice_if_resume),
|
||||
DEVMETHOD(ifdi_needs_restart, ice_if_needs_restart),
|
||||
#ifdef PCI_IOV
|
||||
DEVMETHOD(ifdi_iov_vf_add, ice_if_iov_vf_add),
|
||||
DEVMETHOD(ifdi_iov_init, ice_if_iov_init),
|
||||
DEVMETHOD(ifdi_iov_uninit, ice_if_iov_uninit),
|
||||
DEVMETHOD(ifdi_vflr_handle, ice_if_vflr_handle),
|
||||
#endif
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
|
@ -733,6 +753,9 @@ ice_update_link_status(struct ice_softc *sc, bool update_media)
|
|||
iflib_link_state_change(sc->ctx, LINK_STATE_DOWN, 0);
|
||||
ice_rdma_link_change(sc, LINK_STATE_DOWN, 0);
|
||||
}
|
||||
#ifdef PCI_IOV
|
||||
ice_vc_notify_all_vfs_link_state(sc);
|
||||
#endif
|
||||
update_media = true;
|
||||
}
|
||||
|
||||
|
|
@ -831,6 +854,14 @@ ice_if_attach_post(if_ctx_t ctx)
|
|||
|
||||
ice_add_device_sysctls(sc);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_SRIOV)) {
|
||||
err = ice_iov_attach(sc);
|
||||
if (err == ENOMEM)
|
||||
return (err);
|
||||
}
|
||||
#endif /* PCI_IOV */
|
||||
|
||||
/* Get DCBX/LLDP state and start DCBX agent */
|
||||
ice_init_dcb_setup(sc);
|
||||
|
||||
|
|
@ -953,6 +984,11 @@ ice_if_detach(if_ctx_t ctx)
|
|||
ice_destroy_mirror_interface(sc);
|
||||
ice_rdma_pf_detach(sc);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_SRIOV))
|
||||
ice_iov_detach(sc);
|
||||
#endif /* PCI_IOV */
|
||||
|
||||
/* Free allocated media types */
|
||||
ifmedia_removeall(sc->media);
|
||||
|
||||
|
|
@ -2277,7 +2313,12 @@ ice_transition_recovery_mode(struct ice_softc *sc)
|
|||
ice_rdma_pf_detach(sc);
|
||||
ice_clear_bit(ICE_FEATURE_RDMA, sc->feat_cap);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
if (ice_test_and_clear_bit(ICE_FEATURE_SRIOV, sc->feat_en))
|
||||
ice_iov_detach(sc);
|
||||
#else
|
||||
ice_clear_bit(ICE_FEATURE_SRIOV, sc->feat_en);
|
||||
#endif /* PCI_IOV */
|
||||
ice_clear_bit(ICE_FEATURE_SRIOV, sc->feat_cap);
|
||||
|
||||
ice_vsi_del_txqs_ctx(vsi);
|
||||
|
|
@ -2325,7 +2366,12 @@ ice_transition_safe_mode(struct ice_softc *sc)
|
|||
ice_rdma_pf_detach(sc);
|
||||
ice_clear_bit(ICE_FEATURE_RDMA, sc->feat_cap);
|
||||
|
||||
#ifdef PCI_IOV
|
||||
if (ice_test_and_clear_bit(ICE_FEATURE_SRIOV, sc->feat_en))
|
||||
ice_iov_detach(sc);
|
||||
#else
|
||||
ice_clear_bit(ICE_FEATURE_SRIOV, sc->feat_en);
|
||||
#endif /* PCI_IOV */
|
||||
ice_clear_bit(ICE_FEATURE_SRIOV, sc->feat_cap);
|
||||
|
||||
ice_clear_bit(ICE_FEATURE_RSS, sc->feat_cap);
|
||||
|
|
@ -3349,6 +3395,77 @@ ice_init_link(struct ice_softc *sc)
|
|||
|
||||
}
|
||||
|
||||
#ifdef PCI_IOV
|
||||
/**
|
||||
* ice_if_iov_init - iov init handler for iflib
|
||||
* @ctx: iflib context pointer
|
||||
* @num_vfs: number of VFs to create
|
||||
* @params: configuration parameters for the PF
|
||||
*
|
||||
* Configure the driver for SR-IOV mode. Used to setup things like memory
|
||||
* before any VFs are created.
|
||||
*
|
||||
* @remark This is a wrapper for ice_iov_init
|
||||
*/
|
||||
static int
|
||||
ice_if_iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params)
|
||||
{
|
||||
struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
|
||||
|
||||
return ice_iov_init(sc, num_vfs, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_if_iov_uninit - iov uninit handler for iflib
|
||||
* @ctx: iflib context pointer
|
||||
*
|
||||
* Destroys VFs and frees their memory and resources.
|
||||
*
|
||||
* @remark This is a wrapper for ice_iov_uninit
|
||||
*/
|
||||
static void
|
||||
ice_if_iov_uninit(if_ctx_t ctx)
|
||||
{
|
||||
struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
|
||||
|
||||
ice_iov_uninit(sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_if_iov_vf_add - iov add vf handler for iflib
|
||||
* @ctx: iflib context pointer
|
||||
* @vfnum: index of VF to configure
|
||||
* @params: configuration parameters for the VF
|
||||
*
|
||||
* Sets up the VF given by the vfnum index. This is called by the OS
|
||||
* for each VF created by the PF driver after it is spawned.
|
||||
*
|
||||
* @remark This is a wrapper for ice_iov_vf_add
|
||||
*/
|
||||
static int
|
||||
ice_if_iov_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params)
|
||||
{
|
||||
struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
|
||||
|
||||
return ice_iov_add_vf(sc, vfnum, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_if_vflr_handle - iov VFLR handler
|
||||
* @ctx: iflib context pointer
|
||||
*
|
||||
* Performs the necessar teardown or setup required for a VF after
|
||||
* a VFLR is initiated.
|
||||
*
|
||||
* @remark This is unimplemented
|
||||
*/
|
||||
static void
|
||||
ice_if_vflr_handle(if_ctx_t ctx __unused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* PCI_IOV */
|
||||
|
||||
extern struct if_txrx ice_subif_txrx;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ SRCS += opt_inet.h opt_inet6.h opt_rss.h opt_iflib.h
|
|||
SRCS += ice_lib.c ice_osdep.c ice_resmgr.c ice_strings.c
|
||||
SRCS += ice_iflib_recovery_txrx.c ice_iflib_txrx.c if_ice_iflib.c
|
||||
SRCS += ice_fw_logging.c ice_ddp_common.c
|
||||
SRCS.PCI_IOV += pci_iov_if.h ice_iov.c ice_vf_mbx.c
|
||||
|
||||
# RDMA Client interface
|
||||
# TODO: Is this the right way to compile this?
|
||||
|
|
|
|||
Loading…
Reference in a new issue