Skip to content

Commit 59f4d59

Browse files
pgreenwaanguy11
authored andcommitted
ice: add E830 HW VF mailbox message limit support
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 <[email protected]> Reviewed-by: Alexander Lobakin <[email protected]> Tested-by: Rafal Romanowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent b699c81 commit 59f4d59

File tree

9 files changed

+96
-13
lines changed

9 files changed

+96
-13
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ enum ice_feature {
207207
ICE_F_GNSS,
208208
ICE_F_ROCE_LAG,
209209
ICE_F_SRIOV_LAG,
210+
ICE_F_MBX_LIMIT,
210211
ICE_F_MAX
211212
};
212213

drivers/net/ethernet/intel/ice/ice_hw_autogen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,5 +539,8 @@
539539
#define E830_PRTMAC_CL01_QNT_THR_CL0_M GENMASK(15, 0)
540540
#define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4))
541541
#define VFINT_DYN_CTLN_CLEARPBA_M BIT(1)
542+
#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH 0x00234000
543+
#define E830_MBX_VF_DEC_TRIG(_VF) (0x00233800 + (_VF) * 4)
544+
#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF) (0x00233000 + (_VF) * 4)
542545

543546
#endif /* _ICE_HW_AUTOGEN_H_ */

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,6 +3880,9 @@ void ice_init_feature_support(struct ice_pf *pf)
38803880
default:
38813881
break;
38823882
}
3883+
3884+
if (pf->hw.mac_type == ICE_MAC_E830)
3885+
ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
38833886
}
38843887

38853888
/**

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,12 +1563,20 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
15631563
ice_vf_lan_overflow_event(pf, &event);
15641564
break;
15651565
case ice_mbx_opc_send_msg_to_pf:
1566-
data.num_msg_proc = i;
1567-
data.num_pending_arq = pending;
1568-
data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries;
1569-
data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK;
1566+
if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
1567+
ice_vc_process_vf_msg(pf, &event, NULL);
1568+
ice_mbx_vf_dec_trig_e830(hw, &event);
1569+
} else {
1570+
u16 val = hw->mailboxq.num_rq_entries;
1571+
1572+
data.max_num_msgs_mbx = val;
1573+
val = ICE_MBX_OVERFLOW_WATERMARK;
1574+
data.async_watermark_val = val;
1575+
data.num_msg_proc = i;
1576+
data.num_pending_arq = pending;
15701577

1571-
ice_vc_process_vf_msg(pf, &event, &data);
1578+
ice_vc_process_vf_msg(pf, &event, &data);
1579+
}
15721580
break;
15731581
case ice_aqc_opc_fw_logs_event:
15741582
ice_get_fwlog_data(pf, &event);
@@ -4099,7 +4107,11 @@ static int ice_init_pf(struct ice_pf *pf)
40994107

41004108
mutex_init(&pf->vfs.table_lock);
41014109
hash_init(pf->vfs.table);
4102-
ice_mbx_init_snapshot(&pf->hw);
4110+
if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
4111+
wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH,
4112+
ICE_MBX_OVERFLOW_WATERMARK);
4113+
else
4114+
ice_mbx_init_snapshot(&pf->hw);
41034115

41044116
xa_init(&pf->dyn_ports);
41054117
xa_init(&pf->sf_nums);

drivers/net/ethernet/intel/ice/ice_sriov.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ void ice_free_vfs(struct ice_pf *pf)
194194
}
195195

196196
/* clear malicious info since the VF is getting released */
197-
list_del(&vf->mbx_info.list_entry);
197+
if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
198+
list_del(&vf->mbx_info.list_entry);
198199

199200
mutex_unlock(&vf->cfg_lock);
200201
}

drivers/net/ethernet/intel/ice/ice_vf_lib.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
709709
return 0;
710710
}
711711

712+
/**
713+
* ice_reset_vf_mbx_cnt - reset VF mailbox message count
714+
* @vf: pointer to the VF structure
715+
*
716+
* This function clears the VF mailbox message count, and should be called on
717+
* VF reset.
718+
*/
719+
static void ice_reset_vf_mbx_cnt(struct ice_vf *vf)
720+
{
721+
struct ice_pf *pf = vf->pf;
722+
723+
if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
724+
ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
725+
else
726+
ice_mbx_clear_malvf(&vf->mbx_info);
727+
}
728+
712729
/**
713730
* ice_reset_all_vfs - reset all allocated VFs in one go
714731
* @pf: pointer to the PF structure
@@ -735,7 +752,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
735752

736753
/* clear all malicious info if the VFs are getting reset */
737754
ice_for_each_vf(pf, bkt, vf)
738-
ice_mbx_clear_malvf(&vf->mbx_info);
755+
ice_reset_vf_mbx_cnt(vf);
739756

740757
/* If VFs have been disabled, there is no need to reset */
741758
if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
@@ -951,7 +968,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
951968
ice_eswitch_update_repr(&vf->repr_id, vsi);
952969

953970
/* if the VF has been reset allow it to come up again */
954-
ice_mbx_clear_malvf(&vf->mbx_info);
971+
ice_reset_vf_mbx_cnt(vf);
955972

956973
out_unlock:
957974
if (lag && lag->bonded && lag->primary &&
@@ -1004,7 +1021,10 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
10041021
ice_vf_fdir_init(vf);
10051022

10061023
/* Initialize mailbox info for this VF */
1007-
ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
1024+
if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
1025+
ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
1026+
else
1027+
ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
10081028

10091029
mutex_init(&vf->cfg_lock);
10101030
}

drivers/net/ethernet/intel/ice/ice_vf_mbx.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
210210
return 0;
211211
}
212212

213+
/**
214+
* ice_mbx_vf_dec_trig_e830 - Decrements the VF mailbox queue counter
215+
* @hw: pointer to the HW struct
216+
* @event: pointer to the control queue receive event
217+
*
218+
* This function triggers to decrement the counter
219+
* MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes
220+
* the buffers at the PF mailbox queue.
221+
*/
222+
void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
223+
const struct ice_rq_event_info *event)
224+
{
225+
u16 vfid = le16_to_cpu(event->desc.retval);
226+
227+
wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1);
228+
}
229+
230+
/**
231+
* ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count
232+
* @hw: pointer to the HW struct
233+
* @vf_id: VF ID in the PF space
234+
*
235+
* This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT, and should
236+
* be called when a VF is created and on VF reset.
237+
*/
238+
void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id)
239+
{
240+
u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id));
241+
242+
wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg);
243+
}
244+
213245
/**
214246
* ice_mbx_vf_state_handler - Handle states of the overflow algorithm
215247
* @hw: pointer to the HW struct

drivers/net/ethernet/intel/ice/ice_vf_mbx.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
1919
u8 *msg, u16 msglen, struct ice_sq_cd *cd);
2020

2121
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
22+
void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
23+
const struct ice_rq_event_info *event);
24+
void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id);
2225
int
2326
ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
2427
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)
4750
{
4851
}
4952

53+
static inline void
54+
ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
55+
const struct ice_rq_event_info *event)
56+
{
57+
}
58+
5059
#endif /* CONFIG_PCI_IOV */
5160
#endif /* _ICE_VF_MBX_H_ */

drivers/net/ethernet/intel/ice/ice_virtchnl.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4009,8 +4009,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata)
40094009
* @event: pointer to the AQ event
40104010
* @mbxdata: information used to detect VF attempting mailbox overflow
40114011
*
4012-
* called from the common asq/arq handler to
4013-
* process request from VF
4012+
* Called from the common asq/arq handler to process request from VF. When this
4013+
* flow is used for devices with hardware VF to PF message queue overflow
4014+
* support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf
4015+
* check is skipped.
40144016
*/
40154017
void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
40164018
struct ice_mbx_data *mbxdata)
@@ -4036,7 +4038,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
40364038
mutex_lock(&vf->cfg_lock);
40374039

40384040
/* Check if the VF is trying to overflow the mailbox */
4039-
if (ice_is_malicious_vf(vf, mbxdata))
4041+
if (mbxdata && ice_is_malicious_vf(vf, mbxdata))
40404042
goto finish;
40414043

40424044
/* Check if VF is disabled. */

0 commit comments

Comments
 (0)