]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ixgbevf: fix mailbox API compatibility by negotiating supported features
authorJedrzej Jagielski <jedrzej.jagielski@intel.com>
Mon, 20 Oct 2025 19:53:48 +0000 (15:53 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:04:42 +0000 (14:04 +0100)
[ Upstream commit a7075f501bd33c93570af759b6f4302ef0175168 ]

There was backward compatibility in the terms of mailbox API. Various
drivers from various OSes supporting 10G adapters from Intel portfolio
could easily negotiate mailbox API.

This convention has been broken since introducing API 1.4.
Commit 0062e7cc955e ("ixgbevf: add VF IPsec offload code") added support
for IPSec which is specific only for the kernel ixgbe driver. None of the
rest of the Intel 10G PF/VF drivers supports it. And actually lack of
support was not included in the IPSec implementation - there were no such
code paths. No possibility to negotiate support for the feature was
introduced along with introduction of the feature itself.

Commit 339f28964147 ("ixgbevf: Add support for new mailbox communication
between PF and VF") increasing API version to 1.5 did the same - it
introduced code supported specifically by the PF ESX driver. It altered API
version for the VF driver in the same time not touching the version
defined for the PF ixgbe driver. It led to additional discrepancies,
as the code provided within API 1.6 cannot be supported for Linux ixgbe
driver as it causes crashes.

The issue was noticed some time ago and mitigated by Jake within the commit
d0725312adf5 ("ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5").
As a result we have regression for IPsec support and after increasing API
to version 1.6 ixgbevf driver stopped to support ESX MBX.

To fix this mess add new mailbox op asking PF driver about supported
features. Basing on a response determine whether to set support for IPSec
and ESX-specific enhanced mailbox.

New mailbox op, for compatibility purposes, must be added within new API
revision, as API version of OOT PF & VF drivers is already increased to
1.6 and doesn't incorporate features negotiate op.

Features negotiation mechanism gives possibility to be extended with new
features when needed in the future.

Reported-by: Jacob Keller <jacob.e.keller@intel.com>
Closes: https://lore.kernel.org/intel-wired-lan/20241101-jk-ixgbevf-mailbox-v1-5-fixes-v1-0-f556dc9a66ed@intel.com/
Fixes: 0062e7cc955e ("ixgbevf: add VF IPsec offload code")
Fixes: 339f28964147 ("ixgbevf: Add support for new mailbox communication between PF and VF")
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20251009-jk-iwl-net-2025-10-01-v3-4-ef32a425b92a@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/intel/ixgbevf/ipsec.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/intel/ixgbevf/mbx.h
drivers/net/ethernet/intel/ixgbevf/vf.c
drivers/net/ethernet/intel/ixgbevf/vf.h

index 74c121d7abc9097eccb950744d0398016cc830e3..9e92c7732c7bcdc903db24c21f0809c922c58d0d 100644 (file)
@@ -269,6 +269,9 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
        adapter = netdev_priv(dev);
        ipsec = adapter->ipsec;
 
+       if (!(adapter->pf_features & IXGBEVF_PF_SUP_IPSEC))
+               return -EOPNOTSUPP;
+
        if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
                netdev_err(dev, "Unsupported protocol 0x%04x for IPsec offload\n",
                           xs->id.proto);
@@ -394,6 +397,9 @@ static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs)
        adapter = netdev_priv(dev);
        ipsec = adapter->ipsec;
 
+       if (!(adapter->pf_features & IXGBEVF_PF_SUP_IPSEC))
+               return;
+
        if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
                sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;
 
@@ -622,6 +628,10 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter)
        size_t size;
 
        switch (adapter->hw.api_version) {
+       case ixgbe_mbox_api_17:
+               if (!(adapter->pf_features & IXGBEVF_PF_SUP_IPSEC))
+                       return;
+               break;
        case ixgbe_mbox_api_14:
                break;
        default:
index ca2d61c43b5e9c906586eb79a7039f193281fadf..1e25598cc778d63981874b4b917ad797a7026816 100644 (file)
@@ -366,6 +366,13 @@ struct ixgbevf_adapter {
        /* Interrupt Throttle Rate */
        u32 eitr_param;
 
+       u32 pf_features;
+#define IXGBEVF_PF_SUP_IPSEC           BIT(0)
+#define IXGBEVF_PF_SUP_ESX_MBX         BIT(1)
+
+#define IXGBEVF_SUPPORTED_FEATURES     (IXGBEVF_PF_SUP_IPSEC | \
+                                       IXGBEVF_PF_SUP_ESX_MBX)
+
        struct ixgbevf_hw_stats stats;
 
        unsigned long state;
index 6f06e70bc70c80046c1f52c964b7a63f5eb7866b..290207f158081e6257f9b5d548df08bf8cffe633 100644 (file)
@@ -2268,10 +2268,35 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
        adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
 }
 
+/**
+ * ixgbevf_set_features - Set features supported by PF
+ * @adapter: pointer to the adapter struct
+ *
+ * Negotiate with PF supported features and then set pf_features accordingly.
+ */
+static void ixgbevf_set_features(struct ixgbevf_adapter *adapter)
+{
+       u32 *pf_features = &adapter->pf_features;
+       struct ixgbe_hw *hw = &adapter->hw;
+       int err;
+
+       err = hw->mac.ops.negotiate_features(hw, pf_features);
+       if (err && err != -EOPNOTSUPP)
+               netdev_dbg(adapter->netdev,
+                          "PF feature negotiation failed.\n");
+
+       /* Address also pre API 1.7 cases */
+       if (hw->api_version == ixgbe_mbox_api_14)
+               *pf_features |= IXGBEVF_PF_SUP_IPSEC;
+       else if (hw->api_version == ixgbe_mbox_api_15)
+               *pf_features |= IXGBEVF_PF_SUP_ESX_MBX;
+}
+
 static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        static const int api[] = {
+               ixgbe_mbox_api_17,
                ixgbe_mbox_api_16,
                ixgbe_mbox_api_15,
                ixgbe_mbox_api_14,
@@ -2292,8 +2317,9 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
                idx++;
        }
 
-       /* Following is not supported by API 1.6, it is specific for 1.5 */
-       if (hw->api_version == ixgbe_mbox_api_15) {
+       ixgbevf_set_features(adapter);
+
+       if (adapter->pf_features & IXGBEVF_PF_SUP_ESX_MBX) {
                hw->mbx.ops.init_params(hw);
                memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops,
                       sizeof(struct ixgbe_mbx_operations));
@@ -2651,6 +2677,7 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
                case ixgbe_mbox_api_14:
                case ixgbe_mbox_api_15:
                case ixgbe_mbox_api_16:
+               case ixgbe_mbox_api_17:
                        if (adapter->xdp_prog &&
                            hw->mac.max_tx_queues == rss)
                                rss = rss > 3 ? 2 : 1;
@@ -4645,6 +4672,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        case ixgbe_mbox_api_14:
        case ixgbe_mbox_api_15:
        case ixgbe_mbox_api_16:
+       case ixgbe_mbox_api_17:
                netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE -
                                  (ETH_HLEN + ETH_FCS_LEN);
                break;
index c1494fd1f67b4710b3fbeeaff81cfd1994243bb0..a8ed23ee66aa841d0841a4d778b6af80169f59ba 100644 (file)
@@ -67,6 +67,7 @@ enum ixgbe_pfvf_api_rev {
        ixgbe_mbox_api_14,      /* API version 1.4, linux/freebsd VF driver */
        ixgbe_mbox_api_15,      /* API version 1.5, linux/freebsd VF driver */
        ixgbe_mbox_api_16,      /* API version 1.6, linux/freebsd VF driver */
+       ixgbe_mbox_api_17,      /* API version 1.7, linux/freebsd VF driver */
        /* This value should always be last */
        ixgbe_mbox_api_unknown, /* indicates that API version is not known */
 };
@@ -106,6 +107,9 @@ enum ixgbe_pfvf_api_rev {
 /* mailbox API, version 1.6 VF requests */
 #define IXGBE_VF_GET_PF_LINK_STATE     0x11 /* request PF to send link info */
 
+/* mailbox API, version 1.7 VF requests */
+#define IXGBE_VF_FEATURES_NEGOTIATE    0x12 /* get features supported by PF*/
+
 /* length of permanent address message returned from PF */
 #define IXGBE_VF_PERMADDR_MSG_LEN      4
 /* word in permanent address message with the current multicast type */
index 55ac79f87438f2b0d5bdf39373cfa6d4cb14e9fd..65257107dfc8a4986640c68a6adbd8ee9b0e8b74 100644 (file)
@@ -313,6 +313,7 @@ int ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *reta, int num_rx_queues)
         * is not supported for this device type.
         */
        switch (hw->api_version) {
+       case ixgbe_mbox_api_17:
        case ixgbe_mbox_api_16:
        case ixgbe_mbox_api_15:
        case ixgbe_mbox_api_14:
@@ -383,6 +384,7 @@ int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key)
         * or if the operation is not supported for this device type.
         */
        switch (hw->api_version) {
+       case ixgbe_mbox_api_17:
        case ixgbe_mbox_api_16:
        case ixgbe_mbox_api_15:
        case ixgbe_mbox_api_14:
@@ -555,6 +557,7 @@ static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
        case ixgbe_mbox_api_14:
        case ixgbe_mbox_api_15:
        case ixgbe_mbox_api_16:
+       case ixgbe_mbox_api_17:
                break;
        default:
                return -EOPNOTSUPP;
@@ -646,6 +649,7 @@ static int ixgbevf_get_pf_link_state(struct ixgbe_hw *hw, ixgbe_link_speed *spee
 
        switch (hw->api_version) {
        case ixgbe_mbox_api_16:
+       case ixgbe_mbox_api_17:
                break;
        default:
                return -EOPNOTSUPP;
@@ -669,6 +673,42 @@ static int ixgbevf_get_pf_link_state(struct ixgbe_hw *hw, ixgbe_link_speed *spee
        return err;
 }
 
+/**
+ * ixgbevf_negotiate_features_vf - negotiate supported features with PF driver
+ * @hw: pointer to the HW structure
+ * @pf_features: bitmask of features supported by PF
+ *
+ * Return: IXGBE_ERR_MBX in the  case of mailbox error,
+ * -EOPNOTSUPP if the op is not supported or 0 on success.
+ */
+static int ixgbevf_negotiate_features_vf(struct ixgbe_hw *hw, u32 *pf_features)
+{
+       u32 msgbuf[2] = {};
+       int err;
+
+       switch (hw->api_version) {
+       case ixgbe_mbox_api_17:
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       msgbuf[0] = IXGBE_VF_FEATURES_NEGOTIATE;
+       msgbuf[1] = IXGBEVF_SUPPORTED_FEATURES;
+
+       err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf,
+                                        ARRAY_SIZE(msgbuf));
+
+       if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) {
+               err = IXGBE_ERR_MBX;
+               *pf_features = 0x0;
+       } else {
+               *pf_features = msgbuf[1];
+       }
+
+       return err;
+}
+
 /**
  *  ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
  *  @hw: pointer to the HW structure
@@ -799,6 +839,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
                                     bool *link_up,
                                     bool autoneg_wait_to_complete)
 {
+       struct ixgbevf_adapter *adapter = hw->back;
        struct ixgbe_mbx_info *mbx = &hw->mbx;
        struct ixgbe_mac_info *mac = &hw->mac;
        s32 ret_val = 0;
@@ -825,7 +866,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
         * until we are called again and don't report an error
         */
        if (mbx->ops.read(hw, &in_msg, 1)) {
-               if (hw->api_version >= ixgbe_mbox_api_15)
+               if (adapter->pf_features & IXGBEVF_PF_SUP_ESX_MBX)
                        mac->get_link_status = false;
                goto out;
        }
@@ -1026,6 +1067,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
        case ixgbe_mbox_api_14:
        case ixgbe_mbox_api_15:
        case ixgbe_mbox_api_16:
+       case ixgbe_mbox_api_17:
                break;
        default:
                return 0;
@@ -1080,6 +1122,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
        .setup_link             = ixgbevf_setup_mac_link_vf,
        .check_link             = ixgbevf_check_mac_link_vf,
        .negotiate_api_version  = ixgbevf_negotiate_api_version_vf,
+       .negotiate_features     = ixgbevf_negotiate_features_vf,
        .set_rar                = ixgbevf_set_rar_vf,
        .update_mc_addr_list    = ixgbevf_update_mc_addr_list_vf,
        .update_xcast_mode      = ixgbevf_update_xcast_mode,
index 2d791bc26ae4e7ddbbd81d4c2636b8f39236f64a..4f19b8900c29a32c5b2f598d0f7d4a0603a7d4eb 100644 (file)
@@ -26,6 +26,7 @@ struct ixgbe_mac_operations {
        s32 (*stop_adapter)(struct ixgbe_hw *);
        s32 (*get_bus_info)(struct ixgbe_hw *);
        s32 (*negotiate_api_version)(struct ixgbe_hw *hw, int api);
+       int (*negotiate_features)(struct ixgbe_hw *hw, u32 *pf_features);
 
        /* Link */
        s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);