i40e: Fix the FD sideband logic to detect a FD table full condition

Hardware does not have a way of telling a PF how much of the global
shared FD table space is still available or is consumed.
Previously, every PF but PF0 would think there was still space available
when there wasn't. The PFs would continue to try to add filters and fail.
With this new logic if a filter programming error is detected we just
check if we are close to the guaranteed space full and that can be used
as a hint to say, there might not be space and we should turn off the
features. This way we can turn off the feature in SW for all PFs in
time.

Change-ID: I725cb2fab16c033f883056362b4542c1400503c5
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Anjali Singhai Jain 2014-06-04 04:22:47 +00:00 committed by Jeff Kirsher
parent 12be846ddd
commit 129573883c
3 changed files with 20 additions and 7 deletions

View File

@ -154,7 +154,7 @@ struct i40e_lump_tracking {
#define I40E_DEFAULT_ATR_SAMPLE_RATE 20 #define I40E_DEFAULT_ATR_SAMPLE_RATE 20
#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512 #define I40E_FDIR_MAX_RAW_PACKET_SIZE 512
#define I40E_FDIR_BUFFER_FULL_MARGIN 10 #define I40E_FDIR_BUFFER_FULL_MARGIN 10
#define I40E_FDIR_BUFFER_HEAD_ROOM 200 #define I40E_FDIR_BUFFER_HEAD_ROOM 32
enum i40e_fd_stat_idx { enum i40e_fd_stat_idx {
I40E_FD_STAT_ATR, I40E_FD_STAT_ATR,
@ -582,6 +582,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input, bool add); struct i40e_fdir_filter *input, bool add);
void i40e_fdir_check_and_reenable(struct i40e_pf *pf); void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
int i40e_get_current_fd_count(struct i40e_pf *pf); int i40e_get_current_fd_count(struct i40e_pf *pf);
int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features); bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
void i40e_set_ethtool_ops(struct net_device *netdev); void i40e_set_ethtool_ops(struct net_device *netdev);
struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,

View File

@ -4944,7 +4944,20 @@ static void i40e_service_event_complete(struct i40e_pf *pf)
} }
/** /**
* i40e_get_current_fd_count - Get the count of FD filters programmed in the HW * i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
* @pf: board private structure
**/
int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
{
int val, fcnt_prog;
val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK);
return fcnt_prog;
}
/**
* i40e_get_current_fd_count - Get the count of total FD filters programmed
* @pf: board private structure * @pf: board private structure
**/ **/
int i40e_get_current_fd_count(struct i40e_pf *pf) int i40e_get_current_fd_count(struct i40e_pf *pf)
@ -4956,7 +4969,6 @@ int i40e_get_current_fd_count(struct i40e_pf *pf)
I40E_PFQF_FDSTAT_BEST_CNT_SHIFT); I40E_PFQF_FDSTAT_BEST_CNT_SHIFT);
return fcnt_prog; return fcnt_prog;
} }
/** /**
* i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
* @pf: board private structure * @pf: board private structure
@ -4971,8 +4983,8 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) && if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(pf->flags & I40E_FLAG_FD_SB_ENABLED)) (pf->flags & I40E_FLAG_FD_SB_ENABLED))
return; return;
fcnt_prog = i40e_get_current_fd_count(pf); fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
fcnt_avail = i40e_get_fd_cnt_all(pf); fcnt_avail = pf->fdir_pf_filter_count;
if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) { if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) {
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) && if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
(pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) { (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {

View File

@ -437,8 +437,8 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
rx_desc->wb.qword0.hi_dword.fd_id); rx_desc->wb.qword0.hi_dword.fd_id);
/* filter programming failed most likely due to table full */ /* filter programming failed most likely due to table full */
fcnt_prog = i40e_get_current_fd_count(pf); fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
fcnt_avail = i40e_get_fd_cnt_all(pf); fcnt_avail = pf->fdir_pf_filter_count;
/* If ATR is running fcnt_prog can quickly change, /* If ATR is running fcnt_prog can quickly change,
* if we are very close to full, it makes sense to disable * if we are very close to full, it makes sense to disable
* FD ATR/SB and then re-enable it when there is room. * FD ATR/SB and then re-enable it when there is room.