]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ice: add E830 HW VF mailbox message limit support
authorPaul Greenwalt <paul.greenwalt@intel.com>
Tue, 20 Aug 2024 21:26:16 +0000 (17:26 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Mar 2025 15:45:41 +0000 (16:45 +0100)
[ Upstream commit 59f4d59b25aec39a015c0949f4ec235c7a839c44 ]

E830 adds hardware support to prevent the VF from overflowing the PF
mailbox with VIRTCHNL messages. E830 will use the hardware feature
(ICE_F_MBX_LIMIT) instead of the software solution ice_is_malicious_vf().

To prevent a VF from overflowing the PF, the PF sets the number of
messages per VF that can be in the PF's mailbox queue
(ICE_MBX_OVERFLOW_WATERMARK). When the PF processes a message from a VF,
the PF decrements the per VF message count using the E830_MBX_VF_DEC_TRIG
register.

Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Stable-dep-of: 79990cf5e7ad ("ice: Fix deinitializing VF in error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_vf_mbx.c
drivers/net/ethernet/intel/ice/ice_vf_mbx.h
drivers/net/ethernet/intel/ice/ice_virtchnl.c

index f943964ec05ae7ee21ebd583f9b5372f7832ffc1..e29a7ffd5f1437e466a0d7b856e8d66a6482c2a6 100644 (file)
@@ -202,6 +202,7 @@ enum ice_feature {
        ICE_F_GNSS,
        ICE_F_ROCE_LAG,
        ICE_F_SRIOV_LAG,
+       ICE_F_MBX_LIMIT,
        ICE_F_MAX
 };
 
index 67519a985b3271679412b4592ce81965ab9cc11a..96f70c0a965980ed4f5515c8e1a809c1381861a5 100644 (file)
 #define E830_PRTMAC_CL01_QNT_THR_CL0_M         GENMASK(15, 0)
 #define VFINT_DYN_CTLN(_i)                     (0x00003800 + ((_i) * 4))
 #define VFINT_DYN_CTLN_CLEARPBA_M              BIT(1)
+#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH   0x00234000
+#define E830_MBX_VF_DEC_TRIG(_VF)              (0x00233800 + (_VF) * 4)
+#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF)      (0x00233000 + (_VF) * 4)
 
 #endif /* _ICE_HW_AUTOGEN_H_ */
index 3a0ef56d3edcac0cfa1304c1b2b62fea9ad8a2a7..1fc4805353eb586e99fc13fb32dfb47e555dc0b7 100644 (file)
@@ -4023,6 +4023,9 @@ void ice_init_feature_support(struct ice_pf *pf)
        default:
                break;
        }
+
+       if (pf->hw.mac_type == ICE_MAC_E830)
+               ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
 }
 
 /**
index ef5d43f2804e7eeebfd8feb72fe86046aa717c92..0ae7bdfff83fb22de27630c89c1bebd75e472408 100644 (file)
@@ -1514,12 +1514,20 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
                        ice_vf_lan_overflow_event(pf, &event);
                        break;
                case ice_mbx_opc_send_msg_to_pf:
-                       data.num_msg_proc = i;
-                       data.num_pending_arq = pending;
-                       data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries;
-                       data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK;
+                       if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
+                               ice_vc_process_vf_msg(pf, &event, NULL);
+                               ice_mbx_vf_dec_trig_e830(hw, &event);
+                       } else {
+                               u16 val = hw->mailboxq.num_rq_entries;
+
+                               data.max_num_msgs_mbx = val;
+                               val = ICE_MBX_OVERFLOW_WATERMARK;
+                               data.async_watermark_val = val;
+                               data.num_msg_proc = i;
+                               data.num_pending_arq = pending;
 
-                       ice_vc_process_vf_msg(pf, &event, &data);
+                               ice_vc_process_vf_msg(pf, &event, &data);
+                       }
                        break;
                case ice_aqc_opc_fw_logging:
                        ice_output_fw_log(hw, &event.desc, event.msg_buf);
@@ -3920,7 +3928,11 @@ static int ice_init_pf(struct ice_pf *pf)
 
        mutex_init(&pf->vfs.table_lock);
        hash_init(pf->vfs.table);
-       ice_mbx_init_snapshot(&pf->hw);
+       if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+               wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH,
+                    ICE_MBX_OVERFLOW_WATERMARK);
+       else
+               ice_mbx_init_snapshot(&pf->hw);
 
        return 0;
 }
index 31314e7540f8cfd059ad4a1ab4fb2c9713221b4c..b82c47f8865b4ccdd7ef785f53b2897921753a9e 100644 (file)
@@ -195,7 +195,8 @@ void ice_free_vfs(struct ice_pf *pf)
                }
 
                /* clear malicious info since the VF is getting released */
-               list_del(&vf->mbx_info.list_entry);
+               if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+                       list_del(&vf->mbx_info.list_entry);
 
                mutex_unlock(&vf->cfg_lock);
        }
index 03b9d7d748518cc6bbc741b9fae360f25794f2e1..3f80ba02f634ee598c488e68d4c71ebb8c9bda17 100644 (file)
@@ -701,6 +701,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
        return 0;
 }
 
+/**
+ * ice_reset_vf_mbx_cnt - reset VF mailbox message count
+ * @vf: pointer to the VF structure
+ *
+ * This function clears the VF mailbox message count, and should be called on
+ * VF reset.
+ */
+static void ice_reset_vf_mbx_cnt(struct ice_vf *vf)
+{
+       struct ice_pf *pf = vf->pf;
+
+       if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+               ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
+       else
+               ice_mbx_clear_malvf(&vf->mbx_info);
+}
+
 /**
  * ice_reset_all_vfs - reset all allocated VFs in one go
  * @pf: pointer to the PF structure
@@ -727,7 +744,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
 
        /* clear all malicious info if the VFs are getting reset */
        ice_for_each_vf(pf, bkt, vf)
-               ice_mbx_clear_malvf(&vf->mbx_info);
+               ice_reset_vf_mbx_cnt(vf);
 
        /* If VFs have been disabled, there is no need to reset */
        if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
@@ -944,7 +961,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
        ice_eswitch_update_repr(vsi);
 
        /* if the VF has been reset allow it to come up again */
-       ice_mbx_clear_malvf(&vf->mbx_info);
+       ice_reset_vf_mbx_cnt(vf);
 
 out_unlock:
        if (lag && lag->bonded && lag->primary &&
@@ -994,7 +1011,10 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
        ice_vf_fdir_init(vf);
 
        /* Initialize mailbox info for this VF */
-       ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
+       if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+               ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
+       else
+               ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
 
        mutex_init(&vf->cfg_lock);
 }
index 40cb4ba0789cede45902c29f21cfd5da824d4ed9..75c8113e58ee92a95f3580ac6840d7792d5b0da5 100644 (file)
@@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
        return 0;
 }
 
+/**
+ * ice_mbx_vf_dec_trig_e830 - 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_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
+                             const 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(const 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
index 44bc030d17e07ab1538f8f27299484ed2c039dc4..684de89e5c5ed798ae1762e34ee6c61d906a3bf4 100644 (file)
@@ -19,6 +19,9 @@ 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_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
+                             const struct ice_rq_event_info *event);
+void ice_mbx_vf_clear_cnt_e830(const 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);
@@ -47,5 +50,11 @@ static inline void ice_mbx_init_snapshot(struct ice_hw *hw)
 {
 }
 
+static inline void
+ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
+                        const struct ice_rq_event_info *event)
+{
+}
+
 #endif /* CONFIG_PCI_IOV */
 #endif /* _ICE_VF_MBX_H_ */
index 9f7268bb2ee3b46bd116fa7af9244103abf704d7..e709b10a29761b4268aa3c549eb311dbf2913956 100644 (file)
@@ -3899,8 +3899,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata)
  * @event: pointer to the AQ event
  * @mbxdata: information used to detect VF attempting mailbox overflow
  *
- * called from the common asq/arq handler to
- * process request from VF
+ * Called from the common asq/arq handler to process request from VF. When this
+ * flow is used for devices with hardware VF to PF message queue overflow
+ * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf
+ * check is skipped.
  */
 void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
                           struct ice_mbx_data *mbxdata)
@@ -3926,7 +3928,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
        mutex_lock(&vf->cfg_lock);
 
        /* Check if the VF is trying to overflow the mailbox */
-       if (ice_is_malicious_vf(vf, mbxdata))
+       if (mbxdata && ice_is_malicious_vf(vf, mbxdata))
                goto finish;
 
        /* Check if VF is disabled. */