ice: Restore filters following reset
Following a reset, Flow Director filters are cleared from the hardware. Rebuild the filters using the software structures containing the filter rules. Signed-off-by: Henry Tieman <henry.w.tieman@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Родитель
2c57ffcb19
Коммит
83af003951
|
@ -566,6 +566,8 @@ int
|
|||
ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
|
||||
u32 *rule_locs);
|
||||
void ice_fdir_release_flows(struct ice_hw *hw);
|
||||
void ice_fdir_replay_flows(struct ice_hw *hw);
|
||||
void ice_fdir_replay_fltrs(struct ice_pf *pf);
|
||||
int ice_fdir_create_dflt_rules(struct ice_pf *pf);
|
||||
int ice_open(struct net_device *netdev);
|
||||
int ice_stop(struct net_device *netdev);
|
||||
|
|
|
@ -348,6 +348,53 @@ void ice_fdir_release_flows(struct ice_hw *hw)
|
|||
ice_fdir_erase_flow_from_hw(hw, ICE_BLK_FD, flow);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fdir_replay_flows - replay HW Flow Director filter info
|
||||
* @hw: pointer to HW instance
|
||||
*/
|
||||
void ice_fdir_replay_flows(struct ice_hw *hw)
|
||||
{
|
||||
int flow;
|
||||
|
||||
for (flow = 0; flow < ICE_FLTR_PTYPE_MAX; flow++) {
|
||||
int tun;
|
||||
|
||||
if (!hw->fdir_prof[flow] || !hw->fdir_prof[flow]->cnt)
|
||||
continue;
|
||||
for (tun = 0; tun < ICE_FD_HW_SEG_MAX; tun++) {
|
||||
struct ice_flow_prof *hw_prof;
|
||||
struct ice_fd_hw_prof *prof;
|
||||
u64 prof_id;
|
||||
int j;
|
||||
|
||||
prof = hw->fdir_prof[flow];
|
||||
prof_id = flow + tun * ICE_FLTR_PTYPE_MAX;
|
||||
ice_flow_add_prof(hw, ICE_BLK_FD, ICE_FLOW_RX, prof_id,
|
||||
prof->fdir_seg[tun], TNL_SEG_CNT(tun),
|
||||
&hw_prof);
|
||||
for (j = 0; j < prof->cnt; j++) {
|
||||
enum ice_flow_priority prio;
|
||||
u64 entry_h = 0;
|
||||
int err;
|
||||
|
||||
prio = ICE_FLOW_PRIO_NORMAL;
|
||||
err = ice_flow_add_entry(hw, ICE_BLK_FD,
|
||||
prof_id,
|
||||
prof->vsi_h[0],
|
||||
prof->vsi_h[j],
|
||||
prio, prof->fdir_seg,
|
||||
&entry_h);
|
||||
if (err) {
|
||||
dev_err(ice_hw_to_dev(hw), "Could not replay Flow Director, flow type %d\n",
|
||||
flow);
|
||||
continue;
|
||||
}
|
||||
prof->entry_h[j][tun] = entry_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_parse_rx_flow_user_data - deconstruct user-defined data
|
||||
* @fsp: pointer to ethtool Rx flow specification
|
||||
|
@ -1225,6 +1272,24 @@ ice_fdir_write_all_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fdir_replay_fltrs - replay filters from the HW filter list
|
||||
* @pf: board private structure
|
||||
*/
|
||||
void ice_fdir_replay_fltrs(struct ice_pf *pf)
|
||||
{
|
||||
struct ice_fdir_fltr *f_rule;
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
|
||||
list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
|
||||
int err = ice_fdir_write_all_fltr(pf, f_rule, true);
|
||||
|
||||
if (err)
|
||||
dev_dbg(ice_pf_to_dev(pf), "Flow Director error %d, could not reprogram filter %d\n",
|
||||
err, f_rule->fltr_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_fdir_create_dflt_rules - create default perfect filters
|
||||
* @pf: PF data structure
|
||||
|
|
|
@ -2748,6 +2748,8 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
|
|||
goto err_vsi;
|
||||
|
||||
ice_vsi_get_qs(vsi);
|
||||
|
||||
ice_alloc_fd_res(vsi);
|
||||
ice_vsi_set_tc_cfg(vsi);
|
||||
|
||||
/* Initialize VSI struct elements and create VSI in FW */
|
||||
|
@ -2756,6 +2758,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
|
|||
goto err_vsi;
|
||||
|
||||
switch (vsi->type) {
|
||||
case ICE_VSI_CTRL:
|
||||
case ICE_VSI_PF:
|
||||
ret = ice_vsi_alloc_q_vectors(vsi);
|
||||
if (ret)
|
||||
|
@ -2780,12 +2783,14 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
|
|||
if (ret)
|
||||
goto err_vectors;
|
||||
}
|
||||
/* Do not exit if configuring RSS had an issue, at least
|
||||
* receive traffic on first queue. Hence no need to capture
|
||||
* return value
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_RSS_ENA, pf->flags))
|
||||
ice_vsi_cfg_rss_lut_key(vsi);
|
||||
/* ICE_VSI_CTRL does not need RSS so skip RSS processing */
|
||||
if (vsi->type != ICE_VSI_CTRL)
|
||||
/* Do not exit if configuring RSS had an issue, at
|
||||
* least receive traffic on first queue. Hence no
|
||||
* need to capture return value
|
||||
*/
|
||||
if (test_bit(ICE_FLAG_RSS_ENA, pf->flags))
|
||||
ice_vsi_cfg_rss_lut_key(vsi);
|
||||
break;
|
||||
case ICE_VSI_VF:
|
||||
ret = ice_vsi_alloc_q_vectors(vsi);
|
||||
|
|
|
@ -4895,6 +4895,21 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
|||
goto err_sched_init_port;
|
||||
}
|
||||
|
||||
if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) {
|
||||
wr32(hw, PFQF_FD_ENA, PFQF_FD_ENA_FD_ENA_M);
|
||||
if (!rd32(hw, PFQF_FD_SIZE)) {
|
||||
u16 unused, guar, b_effort;
|
||||
|
||||
guar = hw->func_caps.fd_fltr_guar;
|
||||
b_effort = hw->func_caps.fd_fltr_best_effort;
|
||||
|
||||
/* force guaranteed filter pool for PF */
|
||||
ice_alloc_fd_guar_item(hw, &unused, guar);
|
||||
/* force shared filter pool for PF */
|
||||
ice_alloc_fd_shrd_item(hw, &unused, b_effort);
|
||||
}
|
||||
}
|
||||
|
||||
if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
|
||||
ice_dcb_rebuild(pf);
|
||||
|
||||
|
@ -4913,6 +4928,22 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
|
|||
}
|
||||
}
|
||||
|
||||
/* If Flow Director is active */
|
||||
if (test_bit(ICE_FLAG_FD_ENA, pf->flags)) {
|
||||
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_CTRL);
|
||||
if (err) {
|
||||
dev_err(dev, "control VSI rebuild failed: %d\n", err);
|
||||
goto err_vsi_rebuild;
|
||||
}
|
||||
|
||||
/* replay HW Flow Director recipes */
|
||||
if (hw->fdir_prof)
|
||||
ice_fdir_replay_flows(hw);
|
||||
|
||||
/* replay Flow Director filters */
|
||||
ice_fdir_replay_fltrs(pf);
|
||||
}
|
||||
|
||||
ice_update_pf_netdev_link(pf);
|
||||
|
||||
/* tell the firmware we are up */
|
||||
|
|
Загрузка…
Ссылка в новой задаче