Skip to content

Commit

Permalink
i40e: remove hw_disabled_flags in favor of using separate flag bits
Browse files Browse the repository at this point in the history
The hw_disabled_flags field was added as a way of signifying that
a feature was automatically or temporarily disabled. However, we
actually only use this for FDir features. Replace its use with new
_AUTO_DISABLED flags instead. This is more readable, because you aren't
setting an *_ENABLED flag to *disable* the feature.

Additionally, clean up a few areas where we used these bits. First, we
don't really need to set the auto-disable flag for ATR if we're fully
disabling the feature via ethtool.

Second, we should always clear the auto-disable bits in case they somehow
got set when the feature was disabled. However, avoid displaying
a message that we've re-enabled the feature.

Third, we shouldn't be re-enabling ATR in the SB ntuple add flow,
because it might have been disabled due to space constraints. Instead,
we should just wait for the fdir_check_and_reenable to be called by the
watchdog.

Overall, this change allows us to simplify some code by removing an
extra field we didn't need, and the result should make it more clear as
to what we're actually doing with these flags.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Jacob Keller authored and Jeff Kirsher committed Apr 30, 2017
1 parent 789f38c commit 47994c1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 52 deletions.
9 changes: 2 additions & 7 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ struct i40e_pf {
#define I40E_FLAG_DCB_ENABLED BIT_ULL(20)
#define I40E_FLAG_FD_SB_ENABLED BIT_ULL(21)
#define I40E_FLAG_FD_ATR_ENABLED BIT_ULL(22)
#define I40E_FLAG_FD_SB_AUTO_DISABLED BIT_ULL(23)
#define I40E_FLAG_FD_ATR_AUTO_DISABLED BIT_ULL(24)
#define I40E_FLAG_PTP BIT_ULL(25)
#define I40E_FLAG_MFP_ENABLED BIT_ULL(26)
#define I40E_FLAG_UDP_FILTER_SYNC BIT_ULL(27)
Expand Down Expand Up @@ -440,13 +442,6 @@ struct i40e_pf {
#define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(57)
#define I40E_FLAG_LEGACY_RX BIT_ULL(58)

/* Tracks features that are disabled due to hw limitations.
* If a bit is set here, it means that the corresponding
* bit in the 'flags' field is cleared i.e that feature
* is disabled
*/
u64 hw_disabled_flags;

struct i40e_client_instance *cinst;
bool stat_offsets_loaded;
struct i40e_hw_port_stats stats;
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -3643,7 +3643,7 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
return -EOPNOTSUPP;

if (pf->hw_disabled_flags & I40E_FLAG_FD_SB_ENABLED)
if (pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED)
return -ENOSPC;

if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) ||
Expand Down Expand Up @@ -4086,12 +4086,12 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
/* Flush current ATR settings if ATR was disabled */
if ((changed_flags & I40E_FLAG_FD_ATR_ENABLED) &&
!(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) {
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
pf->flags |= I40E_FLAG_FD_ATR_AUTO_DISABLED;
set_bit(__I40E_FD_FLUSH_REQUESTED, pf->state);
}

/* Only allow ATR evict on hardware that is capable of handling it */
if (pf->hw_disabled_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE;

if (changed_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT) {
Expand Down
53 changes: 26 additions & 27 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,13 +1050,13 @@ static void i40e_update_pf_stats(struct i40e_pf *pf)
&osd->rx_lpi_count, &nsd->rx_lpi_count);

if (pf->flags & I40E_FLAG_FD_SB_ENABLED &&
!(pf->hw_disabled_flags & I40E_FLAG_FD_SB_ENABLED))
!(pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED))
nsd->fd_sb_status = true;
else
nsd->fd_sb_status = false;

if (pf->flags & I40E_FLAG_FD_ATR_ENABLED &&
!(pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED))
!(pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED))
nsd->fd_atr_status = true;
else
nsd->fd_atr_status = false;
Expand Down Expand Up @@ -6078,31 +6078,30 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
if (test_bit(__I40E_FD_FLUSH_REQUESTED, pf->state))
return;

/* Check if, FD SB or ATR was auto disabled and if there is enough room
* to re-enable
*/
/* Check if we have enough room to re-enable FDir SB capability. */
fcnt_prog = i40e_get_global_fd_count(pf);
fcnt_avail = pf->fdir_pf_filter_count;
if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) ||
(pf->fd_add_err == 0) ||
(i40e_get_current_atr_cnt(pf) < pf->fd_atr_cnt)) {
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
(pf->hw_disabled_flags & I40E_FLAG_FD_SB_ENABLED)) {
pf->hw_disabled_flags &= ~I40E_FLAG_FD_SB_ENABLED;
if (I40E_DEBUG_FD & pf->hw.debug_mask)
if (pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED) {
pf->flags &= ~I40E_FLAG_FD_SB_AUTO_DISABLED;
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
(I40E_DEBUG_FD & pf->hw.debug_mask))
dev_info(&pf->pdev->dev, "FD Sideband/ntuple is being enabled since we have space in the table now\n");
}
}

/* Wait for some more space to be available to turn on ATR. We also
* must check that no existing ntuple rules for TCP are in effect
/* We should wait for even more space before re-enabling ATR.
* Additionally, we cannot enable ATR as long as we still have TCP SB
* rules active.
*/
if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM * 2)) {
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED) &&
(pf->fd_tcp4_filter_cnt == 0)) {
pf->hw_disabled_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
if (I40E_DEBUG_FD & pf->hw.debug_mask)
if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) &&
(pf->fd_tcp4_filter_cnt == 0)) {
if (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED) {
pf->flags &= ~I40E_FLAG_FD_ATR_AUTO_DISABLED;
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(I40E_DEBUG_FD & pf->hw.debug_mask))
dev_info(&pf->pdev->dev, "ATR is being enabled since we have space in the table and there are no conflicting ntuple rules\n");
}
}
Expand Down Expand Up @@ -6153,7 +6152,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
}

pf->fd_flush_timestamp = jiffies;
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
pf->flags |= I40E_FLAG_FD_ATR_AUTO_DISABLED;
/* flush all filters */
wr32(&pf->hw, I40E_PFQF_CTL_1,
I40E_PFQF_CTL_1_CLEARFDTABLE_MASK);
Expand All @@ -6173,7 +6172,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
/* replay sideband filters */
i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]);
if (!disable_atr && !pf->fd_tcp4_filter_cnt)
pf->hw_disabled_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
pf->flags &= ~I40E_FLAG_FD_ATR_AUTO_DISABLED;
clear_bit(__I40E_FD_FLUSH_REQUESTED, pf->state);
if (I40E_DEBUG_FD & pf->hw.debug_mask)
dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
Expand Down Expand Up @@ -8822,9 +8821,9 @@ static int i40e_sw_init(struct i40e_pf *pf)
(pf->hw.aq.api_min_ver > 4))) {
/* Supported in FW API version higher than 1.4 */
pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
pf->hw_disabled_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
} else {
pf->hw_disabled_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
}

pf->eeprom_version = 0xDEAD;
Expand Down Expand Up @@ -8884,16 +8883,16 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
need_reset = true;
i40e_fdir_filter_exit(pf);
}
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
pf->hw_disabled_flags &= ~I40E_FLAG_FD_SB_ENABLED;
pf->flags &= ~(I40E_FLAG_FD_SB_ENABLED |
I40E_FLAG_FD_SB_AUTO_DISABLED);
/* reset fd counters */
pf->fd_add_err = 0;
pf->fd_atr_cnt = 0;
/* if ATR was auto disabled it can be re-enabled. */
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED)) {
pf->hw_disabled_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
if (I40E_DEBUG_FD & pf->hw.debug_mask)
if (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED) {
pf->flags &= ~I40E_FLAG_FD_ATR_AUTO_DISABLED;
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(I40E_DEBUG_FD & pf->hw.debug_mask))
dev_info(&pf->pdev->dev, "ATR re-enabled.\n");
}
}
Expand Down
22 changes: 7 additions & 15 deletions drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,9 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
I40E_DEBUG_FD & pf->hw.debug_mask)
dev_info(&pf->pdev->dev, "Forcing ATR off, sideband rules for TCP/IPv4 flow being applied\n");
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
pf->flags |= I40E_FLAG_FD_ATR_AUTO_DISABLED;
} else {
pf->fd_tcp4_filter_cnt--;
if (pf->fd_tcp4_filter_cnt == 0) {
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
I40E_DEBUG_FD & pf->hw.debug_mask)
dev_info(&pf->pdev->dev, "ATR re-enabled due to no sideband TCP/IPv4 rules\n");
pf->hw_disabled_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
}
}

return 0;
Expand Down Expand Up @@ -597,8 +591,8 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);

if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) &&
(pf->hw_disabled_flags & I40E_FLAG_FD_SB_ENABLED)) {
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED) {
pf->flags |= I40E_FLAG_FD_ATR_AUTO_DISABLED;
set_bit(__I40E_FD_FLUSH_REQUESTED, pf->state);
}

Expand All @@ -611,12 +605,10 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
*/
if (fcnt_prog >= (fcnt_avail - I40E_FDIR_BUFFER_FULL_MARGIN)) {
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
!(pf->hw_disabled_flags &
I40E_FLAG_FD_SB_ENABLED)) {
!(pf->flags & I40E_FLAG_FD_SB_AUTO_DISABLED)) {
pf->flags |= I40E_FLAG_FD_SB_AUTO_DISABLED;
if (I40E_DEBUG_FD & pf->hw.debug_mask)
dev_warn(&pdev->dev, "FD filter space full, new ntuple rules will not be added\n");
pf->hw_disabled_flags |=
I40E_FLAG_FD_SB_ENABLED;
}
}
} else if (error == BIT(I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
Expand Down Expand Up @@ -2312,7 +2304,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED))
return;

if ((pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED))
if (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED)
return;

/* if sampling is disabled do nothing */
Expand Down Expand Up @@ -2346,7 +2338,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
th = (struct tcphdr *)(hdr.network + hlen);

/* Due to lack of space, no more new filters can be programmed */
if (th->syn && (pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED))
if (th->syn && (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED))
return;
if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) {
/* HW ATR eviction will take care of removing filters on FIN
Expand Down

0 comments on commit 47994c1

Please sign in to comment.