git: f6de0a7c94e9 - stable/14 - ice(4): Update to 1.39.13-k

From: Eric Joyner <erj_at_FreeBSD.org>
Date: Wed, 24 Apr 2024 22:15:04 UTC
The branch stable/14 has been updated by erj:

URL: https://cgit.FreeBSD.org/src/commit/?id=f6de0a7c94e9c9e71ef0532e8c06b565abdb7113

commit f6de0a7c94e9c9e71ef0532e8c06b565abdb7113
Author:     Eric Joyner <erj@FreeBSD.org>
AuthorDate: 2024-02-13 06:26:26 +0000
Commit:     Eric Joyner <erj@FreeBSD.org>
CommitDate: 2024-04-24 22:14:48 +0000

    ice(4): Update to 1.39.13-k
    
    - Adds mirror interface functionality
    - Remove unused virtchnl headers
    
    Signed-off-by: Eric Joyner <erj@FreeBSD.org>
    
    Sponsored by:   Intel Corporation
    Tested by:      jeffrey.e.pieper@intel.com
    Differential Revision:  https://reviews.freebsd.org/D44004
    
    (cherry picked from commit 9e54973fc33aa44b77d1c851cb36fcd82dc44cda)
---
 sys/dev/ice/ice_adminq_cmd.h        |   21 +-
 sys/dev/ice/ice_bitops.h            |    4 +-
 sys/dev/ice/ice_common.c            |   43 +-
 sys/dev/ice/ice_common.h            |    8 +-
 sys/dev/ice/ice_controlq.c          |   10 +-
 sys/dev/ice/ice_controlq.h          |    3 +-
 sys/dev/ice/ice_drv_info.h          |   10 +-
 sys/dev/ice/ice_features.h          |    1 -
 sys/dev/ice/ice_flex_pipe.c         |    1 +
 sys/dev/ice/ice_flow.c              |   71 +-
 sys/dev/ice/ice_flow.h              |    8 +-
 sys/dev/ice/ice_hw_autogen.h        |    1 +
 sys/dev/ice/ice_iflib.h             |   32 +-
 sys/dev/ice/ice_iflib_txrx.c        |  352 +++++++++-
 sys/dev/ice/ice_lib.c               |  360 ++++++++--
 sys/dev/ice/ice_lib.h               |   30 +-
 sys/dev/ice/ice_nvm.c               |   33 +-
 sys/dev/ice/ice_nvm.h               |    1 +
 sys/dev/ice/ice_protocol_type.h     |    1 +
 sys/dev/ice/ice_sched.c             |    7 +-
 sys/dev/ice/ice_strings.c           |    6 +
 sys/dev/ice/ice_switch.c            |   31 +-
 sys/dev/ice/ice_switch.h            |    9 +-
 sys/dev/ice/ice_type.h              |   15 +-
 sys/dev/ice/if_ice_iflib.c          | 1266 ++++++++++++++++++++++++++++++++++-
 sys/dev/ice/virtchnl_inline_ipsec.h |  594 ----------------
 sys/dev/ice/virtchnl_lan_desc.h     |    0
 27 files changed, 2134 insertions(+), 784 deletions(-)

diff --git a/sys/dev/ice/ice_adminq_cmd.h b/sys/dev/ice/ice_adminq_cmd.h
index 31e9583494fc..70b56144faf2 100644
--- a/sys/dev/ice/ice_adminq_cmd.h
+++ b/sys/dev/ice/ice_adminq_cmd.h
@@ -152,6 +152,7 @@ struct ice_aqc_list_caps_elem {
 #define ICE_AQC_CAPS_WOL_PROXY				0x0008
 #define ICE_AQC_CAPS_SRIOV				0x0012
 #define ICE_AQC_CAPS_VF					0x0013
+#define ICE_AQC_CAPS_VMDQ				0x0014
 #define ICE_AQC_CAPS_802_1QBG				0x0015
 #define ICE_AQC_CAPS_802_1BR				0x0016
 #define ICE_AQC_CAPS_VSI				0x0017
@@ -184,6 +185,8 @@ struct ice_aqc_list_caps_elem {
 #define ICE_AQC_CAPS_DYN_FLATTENING			0x008A
 #define ICE_AQC_CAPS_OROM_RECOVERY_UPDATE		0x0090
 #define ICE_AQC_CAPS_ROCEV2_LAG				0x0092
+#define ICE_AQC_BIT_ROCEV2_LAG				0x01
+#define ICE_AQC_BIT_SRIOV_LAG				0x02
 
 	u8 major_ver;
 	u8 minor_ver;
@@ -358,6 +361,8 @@ struct ice_aqc_set_port_params {
 #define ICE_AQC_RES_TYPE_FLAG_SHARED			BIT(7)
 #define ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM		BIT(12)
 #define ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX		BIT(13)
+#define ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_SHARED		BIT(14)
+#define ICE_AQC_RES_TYPE_FLAG_SUBSCRIBE_CTL		BIT(15)
 
 #define ICE_AQC_RES_TYPE_FLAG_DEDICATED			0x00
 
@@ -2198,6 +2203,14 @@ struct ice_aqc_nvm {
 
 #define ICE_AQC_NVM_MINSREV_MOD_ID		0x130
 #define ICE_AQC_NVM_TX_TOPO_MOD_ID		0x14B
+#define ICE_AQC_NVM_CMPO_MOD_ID			0x153
+
+/* Cage Max Power override NVM module */
+struct ice_aqc_nvm_cmpo {
+	__le16 length;
+#define ICE_AQC_NVM_CMPO_ENABLE	BIT(8)
+	__le16 cages_cfg[8];
+};
 
 /* Used for reading and writing MinSRev using 0x0701 and 0x0703. Note that the
  * type field is excluded from the section when reading and writing from
@@ -2509,11 +2522,13 @@ enum ice_lut_type {
 	ICE_LUT_VSI = 0,
 	ICE_LUT_PF = 1,
 	ICE_LUT_GLOBAL = 2,
-	ICE_LUT_TYPE_MASK = 3
+	ICE_LUT_TYPE_MASK = 3,
+	ICE_LUT_PF_SMALL = 5, /* yields ICE_LUT_PF when &= ICE_LUT_TYPE_MASK */
 };
 
 enum ice_lut_size {
 	ICE_LUT_VSI_SIZE = 64,
+	ICE_LUT_PF_SMALL_SIZE = 128,
 	ICE_LUT_GLOBAL_SIZE = 512,
 	ICE_LUT_PF_SIZE = 2048,
 };
@@ -2796,7 +2811,7 @@ struct ice_aqc_event_lan_overflow {
 
 /* Debug Dump Internal Data (indirect 0xFF08) */
 struct ice_aqc_debug_dump_internals {
-	u8 cluster_id;
+	__le16 cluster_id; /* Expresses next cluster ID in response */
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_SW			0
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_TXSCHED		2
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_PROFILES		3
@@ -2809,7 +2824,7 @@ struct ice_aqc_debug_dump_internals {
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_L2P			8
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_QUEUE_MNG		9
 #define ICE_AQC_DBG_DUMP_CLUSTER_ID_FULL_CSR_SPACE	21
-	u8 reserved;
+#define ICE_AQC_DBG_DUMP_CLUSTER_ID_MNG_TRANSACTIONS	22
 	__le16 table_id; /* Used only for non-memory clusters */
 	__le32 idx; /* In table entries for tables, in bytes for memory */
 	__le32 addr_high;
diff --git a/sys/dev/ice/ice_bitops.h b/sys/dev/ice/ice_bitops.h
index c7bf3384675e..499ee41228c3 100644
--- a/sys/dev/ice/ice_bitops.h
+++ b/sys/dev/ice/ice_bitops.h
@@ -402,7 +402,7 @@ static inline bool ice_is_any_bit_set(ice_bitmap_t *bitmap, u16 size)
 }
 
 /**
- * ice_cp_bitmap - copy bitmaps.
+ * ice_cp_bitmap - copy bitmaps
  * @dst: bitmap destination
  * @src: bitmap to copy from
  * @size: Size of the bitmaps in bits
@@ -460,7 +460,7 @@ ice_bitmap_hweight(ice_bitmap_t *bm, u16 size)
 }
 
 /**
- * ice_cmp_bitmap - compares two bitmaps.
+ * ice_cmp_bitmap - compares two bitmaps
  * @bmp1: the bitmap to compare
  * @bmp2: the bitmap to compare with bmp1
  * @size: Size of the bitmaps in bits
diff --git a/sys/dev/ice/ice_common.c b/sys/dev/ice/ice_common.c
index 73249cb7add4..ef487bcfd0f4 100644
--- a/sys/dev/ice/ice_common.c
+++ b/sys/dev/ice/ice_common.c
@@ -2319,6 +2319,10 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
 		ice_debug(hw, ICE_DBG_INIT, "%s: sr_iov_1_1 = %d\n", prefix,
 			  caps->sr_iov_1_1);
 		break;
+	case ICE_AQC_CAPS_VMDQ:
+		caps->vmdq = (number == 1);
+		ice_debug(hw, ICE_DBG_INIT, "%s: vmdq = %d\n", prefix, caps->vmdq);
+		break;
 	case ICE_AQC_CAPS_802_1QBG:
 		caps->evb_802_1_qbg = (number == 1);
 		ice_debug(hw, ICE_DBG_INIT, "%s: evb_802_1_qbg = %d\n", prefix, number);
@@ -2404,7 +2408,7 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
 		ice_debug(hw, ICE_DBG_INIT, "%s: iwarp = %d\n", prefix, caps->iwarp);
 		break;
 	case ICE_AQC_CAPS_ROCEV2_LAG:
-		caps->roce_lag = (number == 1);
+		caps->roce_lag = !!(number & ICE_AQC_BIT_ROCEV2_LAG);
 		ice_debug(hw, ICE_DBG_INIT, "%s: roce_lag = %d\n",
 			  prefix, caps->roce_lag);
 		break;
@@ -2726,6 +2730,10 @@ ice_parse_nac_topo_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
 	dev_p->nac_topo.mode = LE32_TO_CPU(cap->number);
 	dev_p->nac_topo.id = LE32_TO_CPU(cap->phys_id) & ICE_NAC_TOPO_ID_M;
 
+	ice_info(hw, "PF is configured in %s mode with IP instance ID %d\n",
+		 (dev_p->nac_topo.mode == 0) ? "primary" : "secondary",
+		 dev_p->nac_topo.id);
+
 	ice_debug(hw, ICE_DBG_INIT, "dev caps: nac topology is_primary = %d\n",
 		  !!(dev_p->nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M));
 	ice_debug(hw, ICE_DBG_INIT, "dev caps: nac topology is_dual = %d\n",
@@ -3060,7 +3068,7 @@ void ice_clear_pxe_mode(struct ice_hw *hw)
 }
 
 /**
- * ice_aq_set_port_params - set physical port parameters.
+ * ice_aq_set_port_params - set physical port parameters
  * @pi: pointer to the port info struct
  * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
  * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
@@ -4058,6 +4066,8 @@ static u16 ice_lut_type_to_size(u16 lut_type)
 		return ICE_LUT_GLOBAL_SIZE;
 	case ICE_LUT_PF:
 		return ICE_LUT_PF_SIZE;
+	case ICE_LUT_PF_SMALL:
+		return ICE_LUT_PF_SMALL_SIZE;
 	default:
 		return 0;
 	}
@@ -4089,6 +4099,8 @@ int ice_lut_size_to_type(int lut_size)
 		return ICE_LUT_GLOBAL;
 	case ICE_LUT_PF_SIZE:
 		return ICE_LUT_PF;
+	case ICE_LUT_PF_SMALL_SIZE:
+		return ICE_LUT_PF_SMALL;
 	default:
 		return -1;
 	}
@@ -4116,8 +4128,8 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params
 
 	vsi_handle = params->vsi_handle;
 	lut = params->lut;
-	lut_type = params->lut_type;
-	lut_size = ice_lut_type_to_size(lut_type);
+	lut_size = ice_lut_type_to_size(params->lut_type);
+	lut_type = params->lut_type & ICE_LUT_TYPE_MASK;
 	cmd_resp = &desc.params.get_set_rss_lut;
 	if (lut_type == ICE_LUT_GLOBAL)
 		glob_lut_idx = params->global_lut_id;
@@ -4773,6 +4785,7 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
  * @buf: dump buffer
  * @buf_size: dump buffer size
  * @ret_buf_size: return buffer size (returned by FW)
+ * @ret_next_cluster: next cluster to read (returned by FW)
  * @ret_next_table: next block to read (returned by FW)
  * @ret_next_index: next index to read (returned by FW)
  * @cd: pointer to command details structure
@@ -4780,10 +4793,10 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
  * Get internal FW/HW data (0xFF08) for debug purposes.
  */
 enum ice_status
-ice_aq_get_internal_data(struct ice_hw *hw, u8 cluster_id, u16 table_id,
+ice_aq_get_internal_data(struct ice_hw *hw, u16 cluster_id, u16 table_id,
 			 u32 start, void *buf, u16 buf_size, u16 *ret_buf_size,
-			 u16 *ret_next_table, u32 *ret_next_index,
-			 struct ice_sq_cd *cd)
+			 u16 *ret_next_cluster, u16 *ret_next_table,
+			 u32 *ret_next_index, struct ice_sq_cd *cd)
 {
 	struct ice_aqc_debug_dump_internals *cmd;
 	struct ice_aq_desc desc;
@@ -4796,7 +4809,7 @@ ice_aq_get_internal_data(struct ice_hw *hw, u8 cluster_id, u16 table_id,
 
 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_debug_dump_internals);
 
-	cmd->cluster_id = cluster_id;
+	cmd->cluster_id = CPU_TO_LE16(cluster_id);
 	cmd->table_id = CPU_TO_LE16(table_id);
 	cmd->idx = CPU_TO_LE32(start);
 
@@ -4805,6 +4818,8 @@ ice_aq_get_internal_data(struct ice_hw *hw, u8 cluster_id, u16 table_id,
 	if (!status) {
 		if (ret_buf_size)
 			*ret_buf_size = LE16_TO_CPU(desc.datalen);
+		if (ret_next_cluster)
+			*ret_next_cluster = LE16_TO_CPU(cmd->cluster_id);
 		if (ret_next_table)
 			*ret_next_table = LE16_TO_CPU(cmd->table_id);
 		if (ret_next_index)
@@ -6051,7 +6066,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
  */
 enum ice_status
 ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
-		 u16 bus_addr, __le16 addr, u8 params, u8 *data,
+		 u16 bus_addr, __le16 addr, u8 params, const u8 *data,
 		 struct ice_sq_cd *cd)
 {
 	struct ice_aq_desc desc = { 0 };
@@ -6183,8 +6198,6 @@ static bool ice_is_fw_min_ver(struct ice_hw *hw, u8 branch, u8 maj, u8 min,
 			if (hw->fw_min_ver == min && hw->fw_patch >= patch)
 				return true;
 		}
-	} else if (hw->fw_branch > branch) {
-		return true;
 	}
 
 	return false;
@@ -6591,10 +6604,14 @@ u32 ice_get_link_speed(u16 index)
  */
 bool ice_fw_supports_fec_dis_auto(struct ice_hw *hw)
 {
-	return ice_is_fw_min_ver(hw, ICE_FW_FEC_DIS_AUTO_BRANCH,
+	return ice_is_fw_min_ver(hw, ICE_FW_VER_BRANCH_E810,
 				 ICE_FW_FEC_DIS_AUTO_MAJ,
 				 ICE_FW_FEC_DIS_AUTO_MIN,
-				 ICE_FW_FEC_DIS_AUTO_PATCH);
+				 ICE_FW_FEC_DIS_AUTO_PATCH) ||
+	       ice_is_fw_min_ver(hw, ICE_FW_VER_BRANCH_E82X,
+				 ICE_FW_FEC_DIS_AUTO_MAJ_E82X,
+				 ICE_FW_FEC_DIS_AUTO_MIN_E82X,
+				 ICE_FW_FEC_DIS_AUTO_PATCH_E82X);
 }
 
 /**
diff --git a/sys/dev/ice/ice_common.h b/sys/dev/ice/ice_common.h
index 024f6f4cdb01..3abfba874b9c 100644
--- a/sys/dev/ice/ice_common.h
+++ b/sys/dev/ice/ice_common.h
@@ -88,10 +88,10 @@ enum ice_status ice_get_caps(struct ice_hw *hw);
 void ice_set_safe_mode_caps(struct ice_hw *hw);
 
 enum ice_status
-ice_aq_get_internal_data(struct ice_hw *hw, u8 cluster_id, u16 table_id,
+ice_aq_get_internal_data(struct ice_hw *hw, u16 cluster_id, u16 table_id,
 			 u32 start, void *buf, u16 buf_size, u16 *ret_buf_size,
-			 u16 *ret_next_table, u32 *ret_next_index,
-			 struct ice_sq_cd *cd);
+			 u16 *ret_next_cluster, u16 *ret_next_table,
+			 u32 *ret_next_index, struct ice_sq_cd *cd);
 
 enum ice_status ice_set_mac_type(struct ice_hw *hw);
 
@@ -352,7 +352,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
 		struct ice_sq_cd *cd);
 enum ice_status
 ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
-		 u16 bus_addr, __le16 addr, u8 params, u8 *data,
+		 u16 bus_addr, __le16 addr, u8 params, const u8 *data,
 		 struct ice_sq_cd *cd);
 enum ice_status
 ice_aq_set_health_status_config(struct ice_hw *hw, u8 event_source,
diff --git a/sys/dev/ice/ice_controlq.c b/sys/dev/ice/ice_controlq.c
index 09816d4a812a..8aa2a7f765a2 100644
--- a/sys/dev/ice/ice_controlq.c
+++ b/sys/dev/ice/ice_controlq.c
@@ -482,7 +482,7 @@ shutdown_sq_out:
 }
 
 /**
- * ice_aq_ver_check - Check the reported AQ API version.
+ * ice_aq_ver_check - Check the reported AQ API version
  * @hw: pointer to the hardware structure
  *
  * Checks if the driver should load on a given AQ API version.
@@ -1037,12 +1037,18 @@ ice_sq_send_cmd_nolock(struct ice_hw *hw, struct ice_ctl_q_info *cq,
 	if (cq->sq.next_to_use == cq->sq.count)
 		cq->sq.next_to_use = 0;
 	wr32(hw, cq->sq.tail, cq->sq.next_to_use);
+	ice_flush(hw);
+
+	/* Wait a short time before initial ice_sq_done() check, to allow
+	 * hardware time for completion.
+	 */
+	ice_usec_delay(5, false);
 
 	do {
 		if (ice_sq_done(hw, cq))
 			break;
 
-		ice_usec_delay(ICE_CTL_Q_SQ_CMD_USEC, false);
+		ice_usec_delay(10, false);
 		total_delay++;
 	} while (total_delay < cq->sq_cmd_timeout);
 
diff --git a/sys/dev/ice/ice_controlq.h b/sys/dev/ice/ice_controlq.h
index 047dd1beaf60..d48d53a37161 100644
--- a/sys/dev/ice/ice_controlq.h
+++ b/sys/dev/ice/ice_controlq.h
@@ -60,8 +60,7 @@ enum ice_ctl_q {
 };
 
 /* Control Queue timeout settings - max delay 1s */
-#define ICE_CTL_Q_SQ_CMD_TIMEOUT	10000 /* Count 10000 times */
-#define ICE_CTL_Q_SQ_CMD_USEC		100   /* Check every 100usec */
+#define ICE_CTL_Q_SQ_CMD_TIMEOUT	100000	/* Count 100000 times */
 #define ICE_CTL_Q_ADMIN_INIT_TIMEOUT	10    /* Count 10 times */
 #define ICE_CTL_Q_ADMIN_INIT_MSEC	100   /* Check every 100msec */
 
diff --git a/sys/dev/ice/ice_drv_info.h b/sys/dev/ice/ice_drv_info.h
index ff13fe99ee27..8e1200e08a64 100644
--- a/sys/dev/ice/ice_drv_info.h
+++ b/sys/dev/ice/ice_drv_info.h
@@ -62,16 +62,16 @@
  * @var ice_rc_version
  * @brief driver release candidate version number
  */
-const char ice_driver_version[] = "1.37.11-k";
+const char ice_driver_version[] = "1.39.13-k";
 const uint8_t ice_major_version = 1;
-const uint8_t ice_minor_version = 37;
-const uint8_t ice_patch_version = 11;
+const uint8_t ice_minor_version = 39;
+const uint8_t ice_patch_version = 13;
 const uint8_t ice_rc_version = 0;
 
 #define PVIDV(vendor, devid, name) \
-	PVID(vendor, devid, name " - 1.37.11-k")
+	PVID(vendor, devid, name " - 1.39.13-k")
 #define PVIDV_OEM(vendor, devid, svid, sdevid, revid, name) \
-	PVID_OEM(vendor, devid, svid, sdevid, revid, name " - 1.37.11-k")
+	PVID_OEM(vendor, devid, svid, sdevid, revid, name " - 1.39.13-k")
 
 /**
  * @var ice_vendor_info_array
diff --git a/sys/dev/ice/ice_features.h b/sys/dev/ice/ice_features.h
index b58af574976d..03b8c63af291 100644
--- a/sys/dev/ice/ice_features.h
+++ b/sys/dev/ice/ice_features.h
@@ -89,7 +89,6 @@ enum feat_list {
 static inline void
 ice_disable_unsupported_features(ice_bitmap_t __unused *bitmap)
 {
-	ice_clear_bit(ICE_FEATURE_SRIOV, bitmap);
 #ifndef DEV_NETMAP
 	ice_clear_bit(ICE_FEATURE_NETMAP, bitmap);
 #endif
diff --git a/sys/dev/ice/ice_flex_pipe.c b/sys/dev/ice/ice_flex_pipe.c
index 943b37746f9d..f103e2aa6e71 100644
--- a/sys/dev/ice/ice_flex_pipe.c
+++ b/sys/dev/ice/ice_flex_pipe.c
@@ -672,6 +672,7 @@ enum ice_status ice_replay_tunnels(struct ice_hw *hw)
 		if (status) {
 			ice_debug(hw, ICE_DBG_PKG, "ERR: 0x%x - destroy tunnel port 0x%x\n",
 				  status, port);
+			hw->tnl.tbl[i].ref = refs;
 			break;
 		}
 
diff --git a/sys/dev/ice/ice_flow.c b/sys/dev/ice/ice_flow.c
index 0cf37159b251..c04f86445767 100644
--- a/sys/dev/ice/ice_flow.c
+++ b/sys/dev/ice/ice_flow.c
@@ -404,12 +404,11 @@ struct ice_flow_prof_params {
 };
 
 #define ICE_FLOW_SEG_HDRS_L3_MASK	\
-	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \
-	 ICE_FLOW_SEG_HDR_ARP)
+	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
 	 ICE_FLOW_SEG_HDR_SCTP)
-/* mask for L4 protocols that are NOT part of IPV4/6 OTHER PTYPE groups */
+/* mask for L4 protocols that are NOT part of IPv4/6 OTHER PTYPE groups */
 #define ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER	\
 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP)
 
@@ -483,15 +482,13 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 
 		if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
 		    (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
-			src = i ?
-				(const ice_bitmap_t *)ice_ptypes_ipv4_il :
+			src = i ? (const ice_bitmap_t *)ice_ptypes_ipv4_il :
 				(const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
 			   (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) {
-			src = i ?
-				(const ice_bitmap_t *)ice_ptypes_ipv6_il :
+			src = i ? (const ice_bitmap_t *)ice_ptypes_ipv6_il :
 				(const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
@@ -645,8 +642,7 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
 	case ICE_FLOW_FIELD_IDX_ICMP_TYPE:
 	case ICE_FLOW_FIELD_IDX_ICMP_CODE:
 		/* ICMP type and code share the same extraction seq. entry */
-		prot_id = (params->prof->segs[seg].hdrs &
-			   ICE_FLOW_SEG_HDR_IPV4) ?
+		prot_id = (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) ?
 			ICE_PROT_ICMP_IL : ICE_PROT_ICMPV6_IL;
 		sib = fld == ICE_FLOW_FIELD_IDX_ICMP_TYPE ?
 			ICE_FLOW_FIELD_IDX_ICMP_CODE :
@@ -1301,20 +1297,20 @@ ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
 	/* set outer most header */
 	if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
-						   ICE_FLOW_SEG_HDR_IPV_FRAG |
-						   ICE_FLOW_SEG_HDR_IPV_OTHER;
+						    ICE_FLOW_SEG_HDR_IPV_FRAG |
+						    ICE_FLOW_SEG_HDR_IPV_OTHER;
 	else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
-						   ICE_FLOW_SEG_HDR_IPV_FRAG |
-						   ICE_FLOW_SEG_HDR_IPV_OTHER;
+						    ICE_FLOW_SEG_HDR_IPV_FRAG |
+						    ICE_FLOW_SEG_HDR_IPV_OTHER;
 	else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4_GRE)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
-						   ICE_FLOW_SEG_HDR_GRE |
-						   ICE_FLOW_SEG_HDR_IPV_OTHER;
+						    ICE_FLOW_SEG_HDR_GRE |
+						    ICE_FLOW_SEG_HDR_IPV_OTHER;
 	else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6_GRE)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
-						   ICE_FLOW_SEG_HDR_GRE |
-						   ICE_FLOW_SEG_HDR_IPV_OTHER;
+						    ICE_FLOW_SEG_HDR_GRE |
+						    ICE_FLOW_SEG_HDR_IPV_OTHER;
 
 	if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS)
 		return ICE_ERR_PARAM;
@@ -1418,11 +1414,14 @@ ice_get_rss_hdr_type(struct ice_flow_prof *prof)
 	if (prof->segs_cnt == ICE_FLOW_SEG_SINGLE) {
 		hdr_type = ICE_RSS_OUTER_HEADERS;
 	} else if (prof->segs_cnt == ICE_FLOW_SEG_MAX) {
-		if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs == ICE_FLOW_SEG_HDR_NONE)
+		const struct ice_flow_seg_info *s;
+
+		s = &prof->segs[ICE_RSS_OUTER_HEADERS];
+		if (s->hdrs == ICE_FLOW_SEG_HDR_NONE)
 			hdr_type = ICE_RSS_INNER_HEADERS;
-		if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs & ICE_FLOW_SEG_HDR_IPV4)
+		if (s->hdrs & ICE_FLOW_SEG_HDR_IPV4)
 			hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV4;
-		if (prof->segs[ICE_RSS_OUTER_HEADERS].hdrs & ICE_FLOW_SEG_HDR_IPV6)
+		if (s->hdrs & ICE_FLOW_SEG_HDR_IPV6)
 			hdr_type = ICE_RSS_INNER_HEADERS_W_OUTER_IPV6;
 	}
 
@@ -1529,13 +1528,14 @@ ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof)
  * [62:63] - Encapsulation flag:
  *	     0 if non-tunneled
  *	     1 if tunneled
- *	     2 for tunneled with outer ipv4
- *	     3 for tunneled with outer ipv6
+ *	     2 for tunneled with outer IPv4
+ *	     3 for tunneled with outer IPv6
  */
-#define ICE_FLOW_GEN_PROFID(hash, hdr, encap) \
-	((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \
+#define ICE_FLOW_GEN_PROFID(hash, hdr, encap)                                \
+	((u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) |                        \
 	       (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \
-	       (((u64)(encap) << ICE_FLOW_PROF_ENCAP_S) & ICE_FLOW_PROF_ENCAP_M)))
+	       (((u64)(encap) << ICE_FLOW_PROF_ENCAP_S) &                    \
+		ICE_FLOW_PROF_ENCAP_M)))
 
 /**
  * ice_add_rss_cfg_sync - add an RSS configuration
@@ -1559,7 +1559,8 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
 		return ICE_ERR_PARAM;
 
 	segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
-			ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
+			   ICE_FLOW_SEG_SINGLE :
+			   ICE_FLOW_SEG_MAX;
 
 	segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
 						      sizeof(*segs));
@@ -1663,18 +1664,16 @@ ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
 	struct ice_rss_hash_cfg local_cfg;
 	enum ice_status status;
 
-	if (!ice_is_vsi_valid(hw, vsi_handle) ||
-	    !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
+	if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
+	    cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
 	    cfg->hash_flds == ICE_HASH_INVALID)
 		return ICE_ERR_PARAM;
 
+	ice_acquire_lock(&hw->rss_locks);
 	local_cfg = *cfg;
 	if (cfg->hdr_type < ICE_RSS_ANY_HEADERS) {
-		ice_acquire_lock(&hw->rss_locks);
 		status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
-		ice_release_lock(&hw->rss_locks);
 	} else {
-		ice_acquire_lock(&hw->rss_locks);
 		local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
 		status = ice_add_rss_cfg_sync(hw, vsi_handle, &local_cfg);
 		if (!status) {
@@ -1682,8 +1681,8 @@ ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
 			status = ice_add_rss_cfg_sync(hw, vsi_handle,
 						      &local_cfg);
 		}
-		ice_release_lock(&hw->rss_locks);
 	}
+	ice_release_lock(&hw->rss_locks);
 
 	return status;
 }
@@ -1707,7 +1706,8 @@ ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle,
 	u8 segs_cnt;
 
 	segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ?
-			ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX;
+			   ICE_FLOW_SEG_SINGLE :
+			   ICE_FLOW_SEG_MAX;
 	segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
 						      sizeof(*segs));
 	if (!segs)
@@ -1762,8 +1762,8 @@ ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
 	struct ice_rss_hash_cfg local_cfg;
 	enum ice_status status;
 
-	if (!ice_is_vsi_valid(hw, vsi_handle) ||
-	    !cfg || cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
+	if (!ice_is_vsi_valid(hw, vsi_handle) || !cfg ||
+	    cfg->hdr_type > ICE_RSS_ANY_HEADERS ||
 	    cfg->hash_flds == ICE_HASH_INVALID)
 		return ICE_ERR_PARAM;
 
@@ -1774,7 +1774,6 @@ ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle,
 	} else {
 		local_cfg.hdr_type = ICE_RSS_OUTER_HEADERS;
 		status = ice_rem_rss_cfg_sync(hw, vsi_handle, &local_cfg);
-
 		if (!status) {
 			local_cfg.hdr_type = ICE_RSS_INNER_HEADERS;
 			status = ice_rem_rss_cfg_sync(hw, vsi_handle,
diff --git a/sys/dev/ice/ice_flow.h b/sys/dev/ice/ice_flow.h
index 0857b325ca7c..31c369c144e0 100644
--- a/sys/dev/ice/ice_flow.h
+++ b/sys/dev/ice/ice_flow.h
@@ -188,14 +188,14 @@ enum ice_flow_avf_hdr_field {
 enum ice_rss_cfg_hdr_type {
 	ICE_RSS_OUTER_HEADERS, /* take outer headers as inputset. */
 	ICE_RSS_INNER_HEADERS, /* take inner headers as inputset. */
-	/* take inner headers as inputset for packet with outer ipv4. */
+	/* take inner headers as inputset for packet with outer IPv4. */
 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4,
-	/* take inner headers as inputset for packet with outer ipv6. */
+	/* take inner headers as inputset for packet with outer IPv6. */
 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6,
 	/* take outer headers first then inner headers as inputset */
-	/* take inner as inputset for GTPoGRE with outer ipv4 + gre. */
+	/* take inner as inputset for GTPoGRE with outer IPv4 + GRE. */
 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV4_GRE,
-	/* take inner as inputset for GTPoGRE with outer ipv6 + gre. */
+	/* take inner as inputset for GTPoGRE with outer IPv6 + GRE. */
 	ICE_RSS_INNER_HEADERS_W_OUTER_IPV6_GRE,
 	ICE_RSS_ANY_HEADERS
 };
diff --git a/sys/dev/ice/ice_hw_autogen.h b/sys/dev/ice/ice_hw_autogen.h
index 6b04bff4b722..8e59ebc76835 100644
--- a/sys/dev/ice/ice_hw_autogen.h
+++ b/sys/dev/ice/ice_hw_autogen.h
@@ -5476,6 +5476,7 @@
 #define GL_MNG_FW_RAM_STAT_MNG_MEM_ECC_ERR_S	1
 #define GL_MNG_FW_RAM_STAT_MNG_MEM_ECC_ERR_M	BIT(1)
 #define GL_MNG_FWSM				0x000B6134 /* Reset Source: POR */
+#define GL_MNG_FWSM_FW_LOADING_M		BIT(30)
 #define GL_MNG_FWSM_FW_MODES_S			0
 #define GL_MNG_FWSM_FW_MODES_M			MAKEMASK(0x7, 0)
 #define GL_MNG_FWSM_RSV0_S			3
diff --git a/sys/dev/ice/ice_iflib.h b/sys/dev/ice/ice_iflib.h
index e9e09851b82c..4ac5fffe5b7e 100644
--- a/sys/dev/ice/ice_iflib.h
+++ b/sys/dev/ice/ice_iflib.h
@@ -192,6 +192,29 @@ struct ice_rx_queue {
 	struct if_irq			que_irq;
 };
 
+/**
+ * @struct ice_mirr_if
+ * @brief structure representing a mirroring interface
+ */
+struct ice_mirr_if {
+	struct ice_softc *back;
+	struct ifnet *ifp;
+	struct ice_vsi *vsi;
+
+	device_t subdev;
+	if_ctx_t subctx;
+	if_softc_ctx_t subscctx;
+
+	u16 num_irq_vectors;
+	u16 *if_imap;
+	u16 *os_imap;
+	struct ice_irq_vector *rx_irqvs;
+
+	u32 state;
+
+	bool if_attached;
+};
+
 /**
  * @struct ice_softc
  * @brief main structure representing one device
@@ -262,7 +285,7 @@ struct ice_softc {
 	struct ice_resmgr rx_qmgr;
 
 	/* Interrupt allocation manager */
-	struct ice_resmgr imgr;
+	struct ice_resmgr dev_imgr;
 	u16 *pf_imap;
 	int lan_vectors;
 
@@ -302,7 +325,7 @@ struct ice_softc {
 	/* NVM link override settings */
 	struct ice_link_default_override_tlv ldo_tlv;
 
-	u16 fw_debug_dump_cluster_mask;
+	u32 fw_debug_dump_cluster_mask;
 
 	struct sx *iflib_ctx_lock;
 
@@ -310,6 +333,11 @@ struct ice_softc {
 	ice_declare_bitmap(feat_cap, ICE_FEATURE_COUNT);
 	ice_declare_bitmap(feat_en, ICE_FEATURE_COUNT);
 
+	struct ice_resmgr os_imgr;
+	/* For mirror interface */
+	struct ice_mirr_if *mirr_if;
+	int extra_vectors;
+	int last_rid;
 };
 
 #endif /* _ICE_IFLIB_H_ */
diff --git a/sys/dev/ice/ice_iflib_txrx.c b/sys/dev/ice/ice_iflib_txrx.c
index f3087c09702a..a090717e7c5e 100644
--- a/sys/dev/ice/ice_iflib_txrx.c
+++ b/sys/dev/ice/ice_iflib_txrx.c
@@ -44,6 +44,18 @@
 /* Tx/Rx hotpath utility functions */
 #include "ice_common_txrx.h"
 
+/*
+ * Driver private implementations
+ */
+static int _ice_ift_txd_encap(struct ice_tx_queue *txq, if_pkt_info_t pi);
+static int _ice_ift_txd_credits_update(struct ice_softc *sc, struct ice_tx_queue *txq, bool clear);
+static int _ice_ift_rxd_available(struct ice_rx_queue *rxq, qidx_t pidx, qidx_t budget);
+static int _ice_ift_rxd_pkt_get(struct ice_rx_queue *rxq, if_rxd_info_t ri);
+static void _ice_ift_rxd_refill(struct ice_rx_queue *rxq, uint32_t pidx,
+				uint64_t *paddrs, uint16_t count);
+static void _ice_ift_rxd_flush(struct ice_softc *sc, struct ice_rx_queue *rxq,
+			       uint32_t pidx);
+
 /*
  * iflib txrx method declarations
  */
@@ -55,6 +67,13 @@ static int ice_ift_rxd_available(void *arg, uint16_t rxqid, qidx_t pidx, qidx_t
 static void ice_ift_rxd_flush(void *arg, uint16_t rxqid, uint8_t flidx, qidx_t pidx);
 static void ice_ift_rxd_refill(void *arg, if_rxd_update_t iru);
 static qidx_t ice_ift_queue_select(void *arg, struct mbuf *m, if_pkt_info_t pi);
+static int ice_ift_txd_credits_update_subif(void *arg, uint16_t txqid, bool clear);
+static int ice_ift_txd_encap_subif(void *arg, if_pkt_info_t pi);
+static void ice_ift_txd_flush_subif(void *arg, uint16_t txqid, qidx_t pidx);
+static int ice_ift_rxd_available_subif(void *arg, uint16_t rxqid, qidx_t pidx, qidx_t budget);
+static int ice_ift_rxd_pkt_get_subif(void *arg, if_rxd_info_t ri);
+static void ice_ift_rxd_refill_subif(void *arg, if_rxd_update_t iru);
+static void ice_ift_rxd_flush_subif(void *arg, uint16_t rxqid, uint8_t flidx, qidx_t pidx);
 
 /* Macro to help extract the NIC mode flexible Rx descriptor fields from the
  * advanced 32byte Rx descriptors.
@@ -82,8 +101,27 @@ struct if_txrx ice_txrx = {
 };
 
 /**
- * ice_ift_txd_encap - prepare Tx descriptors for a packet
- * @arg: the iflib softc structure pointer
+ * @var ice_subif_txrx
+ * @brief Tx/Rx operations for the iflib stack, for subinterfaces
+ *
+ * Structure defining the Tx and Rx related operations that iflib can request
+ * the subinterface driver to perform. These are the main entry points for the
+ * hot path of the transmit and receive paths in the iflib driver.
+ */
+struct if_txrx ice_subif_txrx = {
+	.ift_txd_credits_update = ice_ift_txd_credits_update_subif,
+	.ift_txd_encap = ice_ift_txd_encap_subif,
+	.ift_txd_flush = ice_ift_txd_flush_subif,
+	.ift_rxd_available = ice_ift_rxd_available_subif,
+	.ift_rxd_pkt_get = ice_ift_rxd_pkt_get_subif,
+	.ift_rxd_refill = ice_ift_rxd_refill_subif,
+	.ift_rxd_flush = ice_ift_rxd_flush_subif,
+	.ift_txq_select_v2 = NULL,
+};
+
+/**
+ * _ice_ift_txd_encap - prepare Tx descriptors for a packet
+ * @txq: driver's TX queue context
  * @pi: packet info
  *
  * Prepares and encapsulates the given packet into into Tx descriptors, in
@@ -94,10 +132,8 @@ struct if_txrx ice_txrx = {
  * Return 0 on success, non-zero error code on failure.
  */
 static int
-ice_ift_txd_encap(void *arg, if_pkt_info_t pi)
+_ice_ift_txd_encap(struct ice_tx_queue *txq, if_pkt_info_t pi)
 {
-	struct ice_softc *sc = (struct ice_softc *)arg;
-	struct ice_tx_queue *txq = &sc->pf_vsi.tx_queues[pi->ipi_qsidx];
 	int nsegs = pi->ipi_nsegs;
 	bus_dma_segment_t *segs = pi->ipi_segs;
 	struct ice_tx_desc *txd = NULL;
@@ -156,6 +192,27 @@ ice_ift_txd_encap(void *arg, if_pkt_info_t pi)
 	return (0);
 }
 
+/**
+ * ice_ift_txd_encap - prepare Tx descriptors for a packet
+ * @arg: the iflib softc structure pointer
+ * @pi: packet info
+ *
+ * Prepares and encapsulates the given packet into Tx descriptors, in
+ * preparation for sending to the transmit engine. Sets the necessary context
+ * descriptors for TSO and other offloads, and prepares the last descriptor
+ * for the writeback status.
+ *
+ * Return 0 on success, non-zero error code on failure.
+ */
+static int
+ice_ift_txd_encap(void *arg, if_pkt_info_t pi)
+{
+	struct ice_softc *sc = (struct ice_softc *)arg;
+	struct ice_tx_queue *txq = &sc->pf_vsi.tx_queues[pi->ipi_qsidx];
+
+	return _ice_ift_txd_encap(txq, pi);
+}
+
 /**
  * ice_ift_txd_flush - Flush Tx descriptors to hardware
  * @arg: device specific softc pointer
@@ -176,9 +233,9 @@ ice_ift_txd_flush(void *arg, uint16_t txqid, qidx_t pidx)
 }
 
 /**
- * ice_ift_txd_credits_update - cleanup Tx descriptors
- * @arg: device private softc
- * @txqid: the Tx queue to update
+ * _ice_ift_txd_credits_update - cleanup Tx descriptors
+ * @sc: device private softc
+ * @txq: the Tx queue to update
  * @clear: if false, only report, do not actually clean
  *
  * If clear is false, iflib is asking if we *could* clean up any Tx
@@ -186,13 +243,12 @@ ice_ift_txd_flush(void *arg, uint16_t txqid, qidx_t pidx)
  *
  * If clear is true, iflib is requesting to cleanup and reclaim used Tx
  * descriptors.
+ *
+ * Called by other txd_credits_update functions passed to iflib.
  */
 static int
-ice_ift_txd_credits_update(void *arg, uint16_t txqid, bool clear)
+_ice_ift_txd_credits_update(struct ice_softc *sc __unused, struct ice_tx_queue *txq, bool clear)
 {
-	struct ice_softc *sc = (struct ice_softc *)arg;
-	struct ice_tx_queue *txq = &sc->pf_vsi.tx_queues[txqid];
-
 	qidx_t processed = 0;
 	qidx_t cur, prev, ntxd, rs_cidx;
 	int32_t delta;
@@ -235,9 +291,28 @@ ice_ift_txd_credits_update(void *arg, uint16_t txqid, bool clear)
 }
 
 /**
- * ice_ift_rxd_available - Return number of available Rx packets
+ * ice_ift_txd_credits_update - cleanup PF VSI Tx descriptors
  * @arg: device private softc
- * @rxqid: the Rx queue id
+ * @txqid: the Tx queue to update
+ * @clear: if false, only report, do not actually clean
+ *
+ * Wrapper for _ice_ift_txd_credits_update() meant for TX queues that
+ * belong to the PF VSI.
+ *
+ * @see _ice_ift_txd_credits_update()
+ */
+static int
+ice_ift_txd_credits_update(void *arg, uint16_t txqid, bool clear)
+{
+	struct ice_softc *sc = (struct ice_softc *)arg;
+	struct ice_tx_queue *txq = &sc->pf_vsi.tx_queues[txqid];
+
+	return _ice_ift_txd_credits_update(sc, txq, clear);
+}
+
+/**
+ * _ice_ift_rxd_available - Return number of available Rx packets
+ * @rxq: RX queue driver structure
  * @pidx: descriptor start point
  * @budget: maximum Rx budget
  *
@@ -245,10 +320,8 @@ ice_ift_txd_credits_update(void *arg, uint16_t txqid, bool clear)
  * of the given budget.
  */
 static int
-ice_ift_rxd_available(void *arg, uint16_t rxqid, qidx_t pidx, qidx_t budget)
+_ice_ift_rxd_available(struct ice_rx_queue *rxq, qidx_t pidx, qidx_t budget)
 {
-	struct ice_softc *sc = (struct ice_softc *)arg;
-	struct ice_rx_queue *rxq = &sc->pf_vsi.rx_queues[rxqid];
 	union ice_32b_rx_flex_desc *rxd;
 	uint16_t status0;
 	int cnt, i, nrxd;
@@ -270,21 +343,54 @@ ice_ift_rxd_available(void *arg, uint16_t rxqid, qidx_t pidx, qidx_t budget)
 	return (cnt);
 }
 
+/**
+ * ice_ift_rxd_available - Return number of available Rx packets
+ * @arg: device private softc
+ * @rxqid: the Rx queue id
+ * @pidx: descriptor start point
+ * @budget: maximum Rx budget
+ *
+ * Wrapper for _ice_ift_rxd_available() that provides a function pointer
+ * that iflib requires for RX processing.
+ */
+static int
+ice_ift_rxd_available(void *arg, uint16_t rxqid, qidx_t pidx, qidx_t budget)
+{
+	struct ice_softc *sc = (struct ice_softc *)arg;
+	struct ice_rx_queue *rxq = &sc->pf_vsi.rx_queues[rxqid];
+
+	return _ice_ift_rxd_available(rxq, pidx, budget);
+}
+
 /**
  * ice_ift_rxd_pkt_get - Called by iflib to send data to upper layer
  * @arg: device specific softc
  * @ri: receive packet info
  *
- * This function is called by iflib, and executes in ithread context. It is
- * called by iflib to obtain data which has been DMA'ed into host memory.
- * Returns zero on success, and EBADMSG on failure.
+ * Wrapper function for _ice_ift_rxd_pkt_get() that provides a function pointer
+ * used by iflib for RX packet processing.
  */
 static int
 ice_ift_rxd_pkt_get(void *arg, if_rxd_info_t ri)
 {
 	struct ice_softc *sc = (struct ice_softc *)arg;
-	if_softc_ctx_t scctx = sc->scctx;
 	struct ice_rx_queue *rxq = &sc->pf_vsi.rx_queues[ri->iri_qsidx];
+
+	return _ice_ift_rxd_pkt_get(rxq, ri);
+}
+
+/**
+ * _ice_ift_rxd_pkt_get - Called by iflib to send data to upper layer
+ * @rxq: RX queue driver structure
+ * @ri: receive packet info
+ *
+ * This function is called by iflib, and executes in ithread context. It is
+ * called by iflib to obtain data which has been DMA'ed into host memory.
+ * Returns zero on success, and EBADMSG on failure.
+ */
+static int
+_ice_ift_rxd_pkt_get(struct ice_rx_queue *rxq, if_rxd_info_t ri)
+{
 	union ice_32b_rx_flex_desc *cur;
 	u16 status0, plen, ptype;
 	bool eop;
@@ -341,7 +447,7 @@ ice_ift_rxd_pkt_get(void *arg, if_rxd_info_t ri)
 	/* Get packet type and set checksum flags */
 	ptype = le16toh(cur->wb.ptype_flex_flags0) &
 		ICE_RX_FLEX_DESC_PTYPE_M;
-	if ((scctx->isc_capenable & IFCAP_RXCSUM) != 0)
+	if ((if_getcapenable(ri->iri_ifp) & IFCAP_RXCSUM) != 0)
 		ice_rx_checksum(rxq, &ri->iri_csum_flags,
 				&ri->iri_csum_data, status0, ptype);
 
@@ -357,16 +463,14 @@ ice_ift_rxd_pkt_get(void *arg, if_rxd_info_t ri)
  * @arg: device specific softc structure
  * @iru: the Rx descriptor update structure
  *
- * Update the Rx descriptor indices for a given queue, assigning new physical
- * addresses to the descriptors, preparing them for re-use by the hardware.
+ * Wrapper function for _ice_ift_rxd_refill() that provides a function pointer
+ * used by iflib for RX packet processing.
  */
 static void
 ice_ift_rxd_refill(void *arg, if_rxd_update_t iru)
 {
 	struct ice_softc *sc = (struct ice_softc *)arg;
 	struct ice_rx_queue *rxq;
-	uint32_t next_pidx;
-	int i;
 	uint64_t *paddrs;
 	uint32_t pidx;
 	uint16_t qsidx, count;
@@ -378,6 +482,26 @@ ice_ift_rxd_refill(void *arg, if_rxd_update_t iru)
 
 	rxq = &(sc->pf_vsi.rx_queues[qsidx]);
 
+	_ice_ift_rxd_refill(rxq, pidx, paddrs, count);
+}
+
+/**
+ * _ice_ift_rxd_refill - Prepare Rx descriptors for re-use by hardware
+ * @rxq: RX queue driver structure
+ * @pidx: first index to refill
+ * @paddrs: physical addresses to use
*** 3364 LINES SKIPPED ***