aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e
diff options
context:
space:
mode:
authorAnjali Singhai Jain <anjali.singhai@intel.com>2015-02-27 04:15:28 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-03-07 07:59:46 -0500
commit04294e38a451b37288d61e52fa07ed087c5cdc02 (patch)
treec3be5cfe42d60aa876e0f1bf2af3047ec0e727d1 /drivers/net/ethernet/intel/i40e
parent4205d379b6ff61472a94efe55b9a103582257ab8 (diff)
i40e: FD filters flush policy changes
Since GLQF_FDCNT_0 register now has the right offset, use it to simplify our FD flush flow. If the filter add error happens to be for SB we just auto disable SB. If filter error happens to be for ATR, auto disable ATR and mark the state to FD_FLUSH_REQUESTED. Which gets cleared when flush completes. If we are entering flush too quickly (< 30 seconds) and we have quite a few SB rules, its time to disable ATR for good. Since SB + ATR rules is most likely making the FD table unstable. ATR can be re-enabled by turning ntuple off (ethtool -K ntuple off) and will remain off after turning ntuple on till it gets unstable again. Change-ID: I2154a2e0a5d44851a2f0eb8731e2f1d4a4d1acbc Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h8
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c59
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c20
3 files changed, 67 insertions, 20 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 4fb258ae83c6..f01cdbf015c7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -175,6 +175,7 @@ struct i40e_lump_tracking {
175#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512 175#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512
176#define I40E_FDIR_BUFFER_FULL_MARGIN 10 176#define I40E_FDIR_BUFFER_FULL_MARGIN 10
177#define I40E_FDIR_BUFFER_HEAD_ROOM 32 177#define I40E_FDIR_BUFFER_HEAD_ROOM 32
178#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
178 179
179enum i40e_fd_stat_idx { 180enum i40e_fd_stat_idx {
180 I40E_FD_STAT_ATR, 181 I40E_FD_STAT_ATR,
@@ -636,9 +637,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
636int i40e_add_del_fdir(struct i40e_vsi *vsi, 637int i40e_add_del_fdir(struct i40e_vsi *vsi,
637 struct i40e_fdir_filter *input, bool add); 638 struct i40e_fdir_filter *input, bool add);
638void i40e_fdir_check_and_reenable(struct i40e_pf *pf); 639void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
639int i40e_get_current_fd_count(struct i40e_pf *pf); 640u32 i40e_get_current_fd_count(struct i40e_pf *pf);
640int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf); 641u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
641int i40e_get_current_atr_cnt(struct i40e_pf *pf); 642u32 i40e_get_current_atr_cnt(struct i40e_pf *pf);
643u32 i40e_get_global_fd_count(struct i40e_pf *pf);
642bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features); 644bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
643void i40e_set_ethtool_ops(struct net_device *netdev); 645void i40e_set_ethtool_ops(struct net_device *netdev);
644struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, 646struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index e765bb37ef8c..77099ed93bfb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -5345,9 +5345,9 @@ static void i40e_service_event_complete(struct i40e_pf *pf)
5345 * i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters 5345 * i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
5346 * @pf: board private structure 5346 * @pf: board private structure
5347 **/ 5347 **/
5348int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf) 5348u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
5349{ 5349{
5350 int val, fcnt_prog; 5350 u32 val, fcnt_prog;
5351 5351
5352 val = rd32(&pf->hw, I40E_PFQF_FDSTAT); 5352 val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
5353 fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK); 5353 fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK);
@@ -5355,12 +5355,13 @@ int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
5355} 5355}
5356 5356
5357/** 5357/**
5358 * i40e_get_current_fd_count - Get the count of total FD filters programmed 5358 * i40e_get_current_fd_count - Get total FD filters programmed for this PF
5359 * @pf: board private structure 5359 * @pf: board private structure
5360 **/ 5360 **/
5361int i40e_get_current_fd_count(struct i40e_pf *pf) 5361u32 i40e_get_current_fd_count(struct i40e_pf *pf)
5362{ 5362{
5363 int val, fcnt_prog; 5363 u32 val, fcnt_prog;
5364
5364 val = rd32(&pf->hw, I40E_PFQF_FDSTAT); 5365 val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
5365 fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK) + 5366 fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK) +
5366 ((val & I40E_PFQF_FDSTAT_BEST_CNT_MASK) >> 5367 ((val & I40E_PFQF_FDSTAT_BEST_CNT_MASK) >>
@@ -5369,6 +5370,21 @@ int i40e_get_current_fd_count(struct i40e_pf *pf)
5369} 5370}
5370 5371
5371/** 5372/**
5373 * i40e_get_global_fd_count - Get total FD filters programmed on device
5374 * @pf: board private structure
5375 **/
5376u32 i40e_get_global_fd_count(struct i40e_pf *pf)
5377{
5378 u32 val, fcnt_prog;
5379
5380 val = rd32(&pf->hw, I40E_GLQF_FDCNT_0);
5381 fcnt_prog = (val & I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK) +
5382 ((val & I40E_GLQF_FDCNT_0_BESTCNT_MASK) >>
5383 I40E_GLQF_FDCNT_0_BESTCNT_SHIFT);
5384 return fcnt_prog;
5385}
5386
5387/**
5372 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled 5388 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
5373 * @pf: board private structure 5389 * @pf: board private structure
5374 **/ 5390 **/
@@ -5382,7 +5398,7 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
5382 /* Check if, FD SB or ATR was auto disabled and if there is enough room 5398 /* Check if, FD SB or ATR was auto disabled and if there is enough room
5383 * to re-enable 5399 * to re-enable
5384 */ 5400 */
5385 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); 5401 fcnt_prog = i40e_get_global_fd_count(pf);
5386 fcnt_avail = pf->fdir_pf_filter_count; 5402 fcnt_avail = pf->fdir_pf_filter_count;
5387 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) || 5403 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) ||
5388 (pf->fd_add_err == 0) || 5404 (pf->fd_add_err == 0) ||
@@ -5404,13 +5420,17 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
5404} 5420}
5405 5421
5406#define I40E_MIN_FD_FLUSH_INTERVAL 10 5422#define I40E_MIN_FD_FLUSH_INTERVAL 10
5423#define I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE 30
5407/** 5424/**
5408 * i40e_fdir_flush_and_replay - Function to flush all FD filters and replay SB 5425 * i40e_fdir_flush_and_replay - Function to flush all FD filters and replay SB
5409 * @pf: board private structure 5426 * @pf: board private structure
5410 **/ 5427 **/
5411static void i40e_fdir_flush_and_replay(struct i40e_pf *pf) 5428static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
5412{ 5429{
5430 unsigned long min_flush_time;
5413 int flush_wait_retry = 50; 5431 int flush_wait_retry = 50;
5432 bool disable_atr = false;
5433 int fd_room;
5414 int reg; 5434 int reg;
5415 5435
5416 if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) 5436 if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED)))
@@ -5418,9 +5438,20 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
5418 5438
5419 if (time_after(jiffies, pf->fd_flush_timestamp + 5439 if (time_after(jiffies, pf->fd_flush_timestamp +
5420 (I40E_MIN_FD_FLUSH_INTERVAL * HZ))) { 5440 (I40E_MIN_FD_FLUSH_INTERVAL * HZ))) {
5421 set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); 5441 /* If the flush is happening too quick and we have mostly
5442 * SB rules we should not re-enable ATR for some time.
5443 */
5444 min_flush_time = pf->fd_flush_timestamp
5445 + (I40E_MIN_FD_FLUSH_SB_ATR_UNSTABLE * HZ);
5446 fd_room = pf->fdir_pf_filter_count - pf->fdir_pf_active_filters;
5447
5448 if (!(time_after(jiffies, min_flush_time)) &&
5449 (fd_room < I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR)) {
5450 dev_info(&pf->pdev->dev, "ATR disabled, not enough FD filter space.\n");
5451 disable_atr = true;
5452 }
5453
5422 pf->fd_flush_timestamp = jiffies; 5454 pf->fd_flush_timestamp = jiffies;
5423 pf->auto_disable_flags |= I40E_FLAG_FD_SB_ENABLED;
5424 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED; 5455 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
5425 /* flush all filters */ 5456 /* flush all filters */
5426 wr32(&pf->hw, I40E_PFQF_CTL_1, 5457 wr32(&pf->hw, I40E_PFQF_CTL_1,
@@ -5440,10 +5471,8 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
5440 } else { 5471 } else {
5441 /* replay sideband filters */ 5472 /* replay sideband filters */
5442 i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]); 5473 i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]);
5443 5474 if (!disable_atr)
5444 pf->flags |= I40E_FLAG_FD_ATR_ENABLED; 5475 pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
5445 pf->auto_disable_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
5446 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
5447 clear_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state); 5476 clear_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
5448 dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n"); 5477 dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
5449 } 5478 }
@@ -5454,7 +5483,7 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
5454 * i40e_get_current_atr_count - Get the count of total FD ATR filters programmed 5483 * i40e_get_current_atr_count - Get the count of total FD ATR filters programmed
5455 * @pf: board private structure 5484 * @pf: board private structure
5456 **/ 5485 **/
5457int i40e_get_current_atr_cnt(struct i40e_pf *pf) 5486u32 i40e_get_current_atr_cnt(struct i40e_pf *pf)
5458{ 5487{
5459 return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters; 5488 return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters;
5460} 5489}
@@ -5480,9 +5509,7 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf)
5480 if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED))) 5509 if (!(pf->flags & (I40E_FLAG_FD_SB_ENABLED | I40E_FLAG_FD_ATR_ENABLED)))
5481 return; 5510 return;
5482 5511
5483 if ((pf->fd_add_err >= I40E_MAX_FD_PROGRAM_ERROR) && 5512 if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
5484 (i40e_get_current_atr_cnt(pf) >= pf->fd_atr_cnt) &&
5485 (i40e_get_current_atr_cnt(pf) > pf->fdir_pf_filter_count))
5486 i40e_fdir_flush_and_replay(pf); 5513 i40e_fdir_flush_and_replay(pf);
5487 5514
5488 i40e_fdir_check_and_reenable(pf); 5515 i40e_fdir_check_and_reenable(pf);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 64beea95bce6..cdd5cc13cbeb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -471,12 +471,27 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
471 dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n", 471 dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
472 rx_desc->wb.qword0.hi_dword.fd_id); 472 rx_desc->wb.qword0.hi_dword.fd_id);
473 473
474 /* Check if the programming error is for ATR.
475 * If so, auto disable ATR and set a state for
476 * flush in progress. Next time we come here if flush is in
477 * progress do nothing, once flush is complete the state will
478 * be cleared.
479 */
480 if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
481 return;
482
474 pf->fd_add_err++; 483 pf->fd_add_err++;
475 /* store the current atr filter count */ 484 /* store the current atr filter count */
476 pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf); 485 pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);
477 486
487 if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) &&
488 (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
489 pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED;
490 set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
491 }
492
478 /* filter programming failed most likely due to table full */ 493 /* filter programming failed most likely due to table full */
479 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); 494 fcnt_prog = i40e_get_global_fd_count(pf);
480 fcnt_avail = pf->fdir_pf_filter_count; 495 fcnt_avail = pf->fdir_pf_filter_count;
481 /* If ATR is running fcnt_prog can quickly change, 496 /* If ATR is running fcnt_prog can quickly change,
482 * if we are very close to full, it makes sense to disable 497 * if we are very close to full, it makes sense to disable
@@ -1926,6 +1941,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
1926 if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) 1941 if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED))
1927 return; 1942 return;
1928 1943
1944 if ((pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
1945 return;
1946
1929 /* if sampling is disabled do nothing */ 1947 /* if sampling is disabled do nothing */
1930 if (!tx_ring->atr_sample_rate) 1948 if (!tx_ring->atr_sample_rate)
1931 return; 1949 return;