--- old/usr/src/uts/common/io/i40e/core/README.illumos	Tue Jan 19 01:02:57 2021
+++ new/usr/src/uts/common/io/i40e/core/README.illumos	Tue Jan 19 01:02:57 2021
@@ -9,100 +9,11 @@
 # http://www.illumos.org/license/CDDL.
 #
 
-This directory contains files extracted from the Intel ixl-1.6.10 driver for
-FreeBSD which was later merged with ixl-1.9.9.
+This directory contains files extracted from the Intel FreeBSD ixl
+driver. This uses the FreeBSD stable/12 branch, git SHA
+e88bf6998796b7e286cc4c2590e09a4292b9c5c9. 
 
-The following change modified the common code.
+The following illumos changes have further  modified the common code:
 
 9601 Divide by zero in i40e_get_available_resources()
-
-During the merge to ixl-1.9.9 the following patches were not applied to
-the illumos core.
-
-We don't explicitly recognise/use the _VF mac types.
-====================================================
---- i40e_common.c
-+++ i40e_common.c
-@@ -77,11 +76,11 @@ enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
-                        hw->mac.type = I40E_MAC_X722;
-                        break;
-                case I40E_DEV_ID_X722_VF:
--               case I40E_DEV_ID_X722_A0_VF:
-                        hw->mac.type = I40E_MAC_X722_VF;
-                        break;
-                case I40E_DEV_ID_VF:
-                case I40E_DEV_ID_VF_HV:
-+               case I40E_DEV_ID_ADAPTIVE_VF:
-                        hw->mac.type = I40E_MAC_VF;
-                        break;
-                default:
-
-We don't have these functions in Illumos core.
-==============================================
---- i40e_common.c
-+++ i40e_common.c
-@@ -4537,7 +4687,6 @@ enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
-  * i40e_aq_add_udp_tunnel
-  * @hw: pointer to the hw struct
-  * @udp_port: the UDP port to add in Host byte order
-- * @header_len: length of the tunneling header length in DWords
-  * @protocol_index: protocol index type
-  * @filter_index: pointer to filter index
-  * @cmd_details: pointer to command details structure or NULL
-@@ -6910,7 +7185,7 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
-  * completion before returning.
-  **/
- enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
--                               enum i40e_virtchnl_ops v_opcode,
-+                               enum virtchnl_ops v_opcode,
-                                enum i40e_status_code v_retval,
-                                u8 *msg, u16 msglen,
-                                struct i40e_asq_cmd_details *cmd_details)
-@@ -6949,9 +7224,9 @@ enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
-  * with appropriate information.
-  **/
- void i40e_vf_parse_hw_config(struct i40e_hw *hw,
--                            struct i40e_virtchnl_vf_resource *msg)
-+                            struct virtchnl_vf_resource *msg)
- {
--       struct i40e_virtchnl_vsi_resource *vsi_res;
-+       struct virtchnl_vsi_resource *vsi_res;
-        int i;
-
-        vsi_res = &msg->vsi_res[0];
-@@ -6960,20 +7235,18 @@ void i40e_vf_parse_hw_config(struct i40e_hw *hw,
-        hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
-        hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
-        hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
--       hw->dev_caps.dcb = msg->vf_offload_flags &
--                          I40E_VIRTCHNL_VF_OFFLOAD_L2;
--       hw->dev_caps.fcoe = (msg->vf_offload_flags &
--                            I40E_VIRTCHNL_VF_OFFLOAD_FCOE) ? 1 : 0;
--       hw->dev_caps.iwarp = (msg->vf_offload_flags &
--                             I40E_VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
-+       hw->dev_caps.dcb = msg->vf_cap_flags &
-+                          VIRTCHNL_VF_OFFLOAD_L2;
-+       hw->dev_caps.iwarp = (msg->vf_cap_flags &
-+                             VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
-        for (i = 0; i < msg->num_vsis; i++) {
--               if (vsi_res->vsi_type == I40E_VSI_SRIOV) {
-+               if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
-                        i40e_memcpy(hw->mac.perm_addr,
-                                    vsi_res->default_mac_addr,
--                                   I40E_ETH_LENGTH_OF_ADDRESS,
-+                                   ETH_ALEN,
-                                    I40E_NONDMA_TO_NONDMA);
-                        i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
--                                   I40E_ETH_LENGTH_OF_ADDRESS,
-+                                   ETH_ALEN,
-                                    I40E_NONDMA_TO_NONDMA);
-                }
-                vsi_res++;
-@@ -6990,14 +7263,14 @@ void i40e_vf_parse_hw_config(struct i40e_hw *hw,
-  **/
- enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
- {
--       return i40e_aq_send_msg_to_pf(hw, I40E_VIRTCHNL_OP_RESET_VF,
-+       return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
-                                      I40E_SUCCESS, NULL, 0, NULL);
- }
+13041 i40e_get_available_resources() broken again for X722 part
--- old/usr/src/uts/common/io/i40e/core/i40e_common.c	Tue Jan 19 01:02:57 2021
+++ new/usr/src/uts/common/io/i40e/core/i40e_common.c	Tue Jan 19 01:02:58 2021
@@ -4030,17 +4030,26 @@
 	/* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */
 	p->fcoe = FALSE;
 
+	valid_functions = p->valid_functions;
+	num_functions = 0;
+	while (valid_functions) {
+		if (valid_functions & 1)
+			num_functions++;
+		valid_functions >>= 1;
+	}
+
 	/* count the enabled ports (aka the "not disabled" ports) */
 	hw->num_ports = 0;
 	for (i = 0; i < 4; i++) {
-		u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
+		u32 port_cfg_reg = I40E_PRTGEN_STATUS + (4 * i);
 		u64 port_cfg = 0;
 
 		/* use AQ read to get the physical register offset instead
 		 * of the port relative offset
 		 */
-		i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
-		if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
+		status = i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
+		if ((status == I40E_SUCCESS) &&
+		    (port_cfg & I40E_PRTGEN_STATUS_PORT_VALID_MASK))
 			hw->num_ports++;
 	}
 
@@ -4050,6 +4059,16 @@
 	 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
 	 * physical ports results in wrong partition id calculation and thus
 	 * not supporting WoL.
+	 *
+	 * Porting note: the above comment is no longer directly relevant: we
+	 * read PRTGEN_STATUS instead now, as PRTGEN_CNF was not reliable for
+	 * these parts.  In addition, the claim about having 4 PFs is not
+	 * correct.  For example, an X557-T2 is a dual port mezz card. Forcing
+	 * ports to four here will cause ->num_partitions to be zero.
+	 *
+	 * On the presumption that the hard-coded value is meaningful in some
+	 * cases, though, we'll take the minimal approach of ensuring that we
+	 * never have more ports than functions.
 	 */
 	if (hw->mac.type == I40E_MAC_X722) {
 		if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
@@ -4057,21 +4076,25 @@
 						  2 * I40E_SR_OCP_CFG_WORD0,
 						  sizeof(ocp_cfg_word0),
 						  &ocp_cfg_word0, TRUE, NULL);
+#ifdef __sun__
 			if (status == I40E_SUCCESS &&
+			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED)) {
+				hw->num_ports = 4;
+				if (hw->num_ports > num_functions) {
+					hw->num_ports = num_functions;
+					DEBUGOUT1("clamped 4 OCP ports to %d\n",
+					    (int)hw->num_ports);
+				}
+			}
+#else
+			if (status == I40E_SUCCESS &&
 			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
 				hw->num_ports = 4;
+#endif
 			i40e_release_nvm(hw);
 		}
 	}
 
-	valid_functions = p->valid_functions;
-	num_functions = 0;
-	while (valid_functions) {
-		if (valid_functions & 1)
-			num_functions++;
-		valid_functions >>= 1;
-	}
-
 	/* partition id is 1-based, and functions are evenly spread
 	 * across the ports as partitions
 	 */
@@ -4080,6 +4103,8 @@
 		hw->num_partitions = num_functions / hw->num_ports;
 	}
 
+	VERIFY(hw->num_partitions > 0);
+
 	/* additional HW specific goodies that might
 	 * someday be HW version specific
 	 */
