Skip to content

Commit cf19e5e

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 40GbE Intel Wired LAN Driver Updates 2018-02-12 This series contains updates to i40e and i40evf. Alan fixes a spelling mistake in code comments. Fixes an issue on older firmware versions or NPAR enabled PFs which do not support the I40E_FLAG_DISABLE_FW_LLDP flag and would get into a situation where any attempt to change any priv flag would be forbidden. Alex got busy with the ITR code and made several cleanups and fixes so that we can more easily understand what is going on. The fixes included a computational fix when determining the register offset, as well as a fix for unnecessarily toggling the CLEARPBA bit which could lead to potential lost events if auto-masking is not enabled. Filip adds a necessary delay to recover after a EMP reset when using firmware version 4.33. Paweł adds a warning message for MFP devices when the link-down-on-close flag is set because it may affect other partitions. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 9b2c45d + a0073a4 commit cf19e5e

File tree

12 files changed

+769
-457
lines changed

12 files changed

+769
-457
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ struct i40e_q_vector {
824824
struct i40e_ring_container rx;
825825
struct i40e_ring_container tx;
826826

827+
u8 itr_countdown; /* when 0 should adjust adaptive ITR */
827828
u8 num_ringpairs; /* total number of ring pairs in vector */
828829

829830
cpumask_t affinity_mask;
@@ -832,8 +833,6 @@ struct i40e_q_vector {
832833
struct rcu_head rcu; /* to avoid race with update stats on free */
833834
char name[I40E_INT_NAME_STR_LEN];
834835
bool arm_wb_state;
835-
#define ITR_COUNTDOWN_START 100
836-
u8 itr_countdown; /* when 0 should adjust ITR */
837836
} ____cacheline_internodealigned_in_smp;
838837

839838
/* lan device */

drivers/net/ethernet/intel/i40e/i40e_debugfs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,9 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
315315
i, rx_ring->vsi,
316316
rx_ring->q_vector);
317317
dev_info(&pf->pdev->dev,
318-
" rx_rings[%i]: rx_itr_setting = %d (%s)\n",
319-
i, rx_ring->rx_itr_setting,
320-
ITR_IS_DYNAMIC(rx_ring->rx_itr_setting) ? "dynamic" : "fixed");
318+
" rx_rings[%i]: itr_setting = %d (%s)\n",
319+
i, rx_ring->itr_setting,
320+
ITR_IS_DYNAMIC(rx_ring->itr_setting) ? "dynamic" : "fixed");
321321
}
322322
for (i = 0; i < vsi->num_queue_pairs; i++) {
323323
struct i40e_ring *tx_ring = READ_ONCE(vsi->tx_rings[i]);
@@ -366,9 +366,9 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
366366
" tx_rings[%i]: DCB tc = %d\n",
367367
i, tx_ring->dcb_tc);
368368
dev_info(&pf->pdev->dev,
369-
" tx_rings[%i]: tx_itr_setting = %d (%s)\n",
370-
i, tx_ring->tx_itr_setting,
371-
ITR_IS_DYNAMIC(tx_ring->tx_itr_setting) ? "dynamic" : "fixed");
369+
" tx_rings[%i]: itr_setting = %d (%s)\n",
370+
i, tx_ring->itr_setting,
371+
ITR_IS_DYNAMIC(tx_ring->itr_setting) ? "dynamic" : "fixed");
372372
}
373373
rcu_read_unlock();
374374
dev_info(&pf->pdev->dev,

drivers/net/ethernet/intel/i40e/i40e_ethtool.c

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,14 +2244,14 @@ static int __i40e_get_coalesce(struct net_device *netdev,
22442244
rx_ring = vsi->rx_rings[queue];
22452245
tx_ring = vsi->tx_rings[queue];
22462246

2247-
if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))
2247+
if (ITR_IS_DYNAMIC(rx_ring->itr_setting))
22482248
ec->use_adaptive_rx_coalesce = 1;
22492249

2250-
if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))
2250+
if (ITR_IS_DYNAMIC(tx_ring->itr_setting))
22512251
ec->use_adaptive_tx_coalesce = 1;
22522252

2253-
ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;
2254-
ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;
2253+
ec->rx_coalesce_usecs = rx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
2254+
ec->tx_coalesce_usecs = tx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
22552255

22562256
/* we use the _usecs_high to store/set the interrupt rate limit
22572257
* that the hardware supports, that almost but not quite
@@ -2311,34 +2311,35 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,
23112311
struct i40e_pf *pf = vsi->back;
23122312
struct i40e_hw *hw = &pf->hw;
23132313
struct i40e_q_vector *q_vector;
2314-
u16 vector, intrl;
2314+
u16 intrl;
23152315

23162316
intrl = i40e_intrl_usec_to_reg(vsi->int_rate_limit);
23172317

2318-
rx_ring->rx_itr_setting = ec->rx_coalesce_usecs;
2319-
tx_ring->tx_itr_setting = ec->tx_coalesce_usecs;
2318+
rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
2319+
tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
23202320

23212321
if (ec->use_adaptive_rx_coalesce)
2322-
rx_ring->rx_itr_setting |= I40E_ITR_DYNAMIC;
2322+
rx_ring->itr_setting |= I40E_ITR_DYNAMIC;
23232323
else
2324-
rx_ring->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
2324+
rx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
23252325

23262326
if (ec->use_adaptive_tx_coalesce)
2327-
tx_ring->tx_itr_setting |= I40E_ITR_DYNAMIC;
2327+
tx_ring->itr_setting |= I40E_ITR_DYNAMIC;
23282328
else
2329-
tx_ring->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
2329+
tx_ring->itr_setting &= ~I40E_ITR_DYNAMIC;
23302330

23312331
q_vector = rx_ring->q_vector;
2332-
q_vector->rx.itr = ITR_TO_REG(rx_ring->rx_itr_setting);
2333-
vector = vsi->base_vector + q_vector->v_idx;
2334-
wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1), q_vector->rx.itr);
2332+
q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
23352333

23362334
q_vector = tx_ring->q_vector;
2337-
q_vector->tx.itr = ITR_TO_REG(tx_ring->tx_itr_setting);
2338-
vector = vsi->base_vector + q_vector->v_idx;
2339-
wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1), q_vector->tx.itr);
2335+
q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
23402336

2341-
wr32(hw, I40E_PFINT_RATEN(vector - 1), intrl);
2337+
/* The interrupt handler itself will take care of programming
2338+
* the Tx and Rx ITR values based on the values we have entered
2339+
* into the q_vector, no need to write the values now.
2340+
*/
2341+
2342+
wr32(hw, I40E_PFINT_RATEN(q_vector->reg_idx), intrl);
23422343
i40e_flush(hw);
23432344
}
23442345

@@ -2364,11 +2365,11 @@ static int __i40e_set_coalesce(struct net_device *netdev,
23642365
vsi->work_limit = ec->tx_max_coalesced_frames_irq;
23652366

23662367
if (queue < 0) {
2367-
cur_rx_itr = vsi->rx_rings[0]->rx_itr_setting;
2368-
cur_tx_itr = vsi->tx_rings[0]->tx_itr_setting;
2368+
cur_rx_itr = vsi->rx_rings[0]->itr_setting;
2369+
cur_tx_itr = vsi->tx_rings[0]->itr_setting;
23692370
} else if (queue < vsi->num_queue_pairs) {
2370-
cur_rx_itr = vsi->rx_rings[queue]->rx_itr_setting;
2371-
cur_tx_itr = vsi->tx_rings[queue]->tx_itr_setting;
2371+
cur_rx_itr = vsi->rx_rings[queue]->itr_setting;
2372+
cur_tx_itr = vsi->tx_rings[queue]->itr_setting;
23722373
} else {
23732374
netif_info(pf, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
23742375
vsi->num_queue_pairs - 1);
@@ -2396,7 +2397,7 @@ static int __i40e_set_coalesce(struct net_device *netdev,
23962397
return -EINVAL;
23972398
}
23982399

2399-
if (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
2400+
if (ec->rx_coalesce_usecs > I40E_MAX_ITR) {
24002401
netif_info(pf, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
24012402
return -EINVAL;
24022403
}
@@ -2407,16 +2408,16 @@ static int __i40e_set_coalesce(struct net_device *netdev,
24072408
return -EINVAL;
24082409
}
24092410

2410-
if (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1)) {
2411+
if (ec->tx_coalesce_usecs > I40E_MAX_ITR) {
24112412
netif_info(pf, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
24122413
return -EINVAL;
24132414
}
24142415

24152416
if (ec->use_adaptive_rx_coalesce && !cur_rx_itr)
2416-
ec->rx_coalesce_usecs = I40E_MIN_ITR << 1;
2417+
ec->rx_coalesce_usecs = I40E_MIN_ITR;
24172418

24182419
if (ec->use_adaptive_tx_coalesce && !cur_tx_itr)
2419-
ec->tx_coalesce_usecs = I40E_MIN_ITR << 1;
2420+
ec->tx_coalesce_usecs = I40E_MIN_ITR;
24202421

24212422
intrl_reg = i40e_intrl_usec_to_reg(ec->rx_coalesce_usecs_high);
24222423
vsi->int_rate_limit = INTRL_REG_TO_USEC(intrl_reg);
@@ -4406,6 +4407,8 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
44064407
}
44074408

44084409
flags_complete:
4410+
changed_flags = orig_flags ^ new_flags;
4411+
44094412
/* Before we finalize any flag changes, we need to perform some
44104413
* checks to ensure that the changes are supported and safe.
44114414
*/
@@ -4415,21 +4418,25 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
44154418
!(pf->hw_features & I40E_HW_ATR_EVICT_CAPABLE))
44164419
return -EOPNOTSUPP;
44174420

4418-
/* Disable FW LLDP not supported if NPAR active or if FW
4419-
* API version < 1.7
4421+
/* If the driver detected FW LLDP was disabled on init, this flag could
4422+
* be set, however we do not support _changing_ the flag if NPAR is
4423+
* enabled or FW API version < 1.7. There are situations where older
4424+
* FW versions/NPAR enabled PFs could disable LLDP, however we _must_
4425+
* not allow the user to enable/disable LLDP with this flag on
4426+
* unsupported FW versions.
44204427
*/
4421-
if (new_flags & I40E_FLAG_DISABLE_FW_LLDP) {
4428+
if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
44224429
if (pf->hw.func_caps.npar_enable) {
44234430
dev_warn(&pf->pdev->dev,
4424-
"Unable to stop FW LLDP if NPAR active\n");
4431+
"Unable to change FW LLDP if NPAR active\n");
44254432
return -EOPNOTSUPP;
44264433
}
44274434

44284435
if (pf->hw.aq.api_maj_ver < 1 ||
44294436
(pf->hw.aq.api_maj_ver == 1 &&
44304437
pf->hw.aq.api_min_ver < 7)) {
44314438
dev_warn(&pf->pdev->dev,
4432-
"FW ver does not support stopping FW LLDP\n");
4439+
"FW ver does not support changing FW LLDP\n");
44334440
return -EOPNOTSUPP;
44344441
}
44354442
}
@@ -4439,15 +4446,17 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
44394446
* something else has modified the flags variable since we copied it
44404447
* originally. We'll just punt with an error and log something in the
44414448
* message buffer.
4449+
*
4450+
* This is the point of no return for this function. We need to have
4451+
* checked any discrepancies or misconfigurations and returned
4452+
* EOPNOTSUPP before updating pf->flags here.
44424453
*/
44434454
if (cmpxchg64(&pf->flags, orig_flags, new_flags) != orig_flags) {
44444455
dev_warn(&pf->pdev->dev,
44454456
"Unable to update pf->flags as it was modified by another thread...\n");
44464457
return -EAGAIN;
44474458
}
44484459

4449-
changed_flags = orig_flags ^ new_flags;
4450-
44514460
/* Process any additional changes needed as a result of flag changes.
44524461
* The changed_flags value reflects the list of bits that were
44534462
* changed in the code above.
@@ -4479,6 +4488,12 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
44794488
}
44804489
}
44814490

4491+
if ((changed_flags & pf->flags &
4492+
I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
4493+
(pf->flags & I40E_FLAG_MFP_ENABLED))
4494+
dev_warn(&pf->pdev->dev,
4495+
"Turning on link-down-on-close flag may affect other partitions\n");
4496+
44824497
if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
44834498
if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
44844499
struct i40e_dcbx_config *dcbcfg;

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,15 +3449,20 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
34493449
for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
34503450
struct i40e_q_vector *q_vector = vsi->q_vectors[i];
34513451

3452-
q_vector->itr_countdown = ITR_COUNTDOWN_START;
3453-
q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[i]->rx_itr_setting);
3454-
q_vector->rx.latency_range = I40E_LOW_LATENCY;
3452+
q_vector->rx.next_update = jiffies + 1;
3453+
q_vector->rx.target_itr =
3454+
ITR_TO_REG(vsi->rx_rings[i]->itr_setting);
34553455
wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),
3456-
q_vector->rx.itr);
3457-
q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[i]->tx_itr_setting);
3458-
q_vector->tx.latency_range = I40E_LOW_LATENCY;
3456+
q_vector->rx.target_itr);
3457+
q_vector->rx.current_itr = q_vector->rx.target_itr;
3458+
3459+
q_vector->tx.next_update = jiffies + 1;
3460+
q_vector->tx.target_itr =
3461+
ITR_TO_REG(vsi->tx_rings[i]->itr_setting);
34593462
wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),
3460-
q_vector->tx.itr);
3463+
q_vector->tx.target_itr);
3464+
q_vector->tx.current_itr = q_vector->tx.target_itr;
3465+
34613466
wr32(hw, I40E_PFINT_RATEN(vector - 1),
34623467
i40e_intrl_usec_to_reg(vsi->int_rate_limit));
34633468

@@ -3558,13 +3563,14 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
35583563
u32 val;
35593564

35603565
/* set the ITR configuration */
3561-
q_vector->itr_countdown = ITR_COUNTDOWN_START;
3562-
q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[0]->rx_itr_setting);
3563-
q_vector->rx.latency_range = I40E_LOW_LATENCY;
3564-
wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.itr);
3565-
q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[0]->tx_itr_setting);
3566-
q_vector->tx.latency_range = I40E_LOW_LATENCY;
3567-
wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.itr);
3566+
q_vector->rx.next_update = jiffies + 1;
3567+
q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting);
3568+
wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr);
3569+
q_vector->rx.current_itr = q_vector->rx.target_itr;
3570+
q_vector->tx.next_update = jiffies + 1;
3571+
q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting);
3572+
wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr);
3573+
q_vector->tx.current_itr = q_vector->tx.target_itr;
35683574

35693575
i40e_enable_misc_int_causes(pf);
35703576

@@ -9215,6 +9221,17 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
92159221
}
92169222
i40e_get_oem_version(&pf->hw);
92179223

9224+
if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
9225+
((hw->aq.fw_maj_ver == 4 && hw->aq.fw_min_ver <= 33) ||
9226+
hw->aq.fw_maj_ver < 4) && hw->mac.type == I40E_MAC_XL710) {
9227+
/* The following delay is necessary for 4.33 firmware and older
9228+
* to recover after EMP reset. 200 ms should suffice but we
9229+
* put here 300 ms to be sure that FW is ready to operate
9230+
* after reset.
9231+
*/
9232+
mdelay(300);
9233+
}
9234+
92189235
/* re-verify the eeprom if we just had an EMP reset */
92199236
if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state))
92209237
i40e_verify_eeprom(pf);
@@ -10018,7 +10035,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
1001810035
ring->dcb_tc = 0;
1001910036
if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
1002010037
ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
10021-
ring->tx_itr_setting = pf->tx_itr_default;
10038+
ring->itr_setting = pf->tx_itr_default;
1002210039
vsi->tx_rings[i] = ring++;
1002310040

1002410041
if (!i40e_enabled_xdp_vsi(vsi))
@@ -10036,7 +10053,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
1003610053
if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE)
1003710054
ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
1003810055
set_ring_xdp(ring);
10039-
ring->tx_itr_setting = pf->tx_itr_default;
10056+
ring->itr_setting = pf->tx_itr_default;
1004010057
vsi->xdp_rings[i] = ring++;
1004110058

1004210059
setup_rx:
@@ -10049,7 +10066,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
1004910066
ring->count = vsi->num_desc;
1005010067
ring->size = 0;
1005110068
ring->dcb_tc = 0;
10052-
ring->rx_itr_setting = pf->rx_itr_default;
10069+
ring->itr_setting = pf->rx_itr_default;
1005310070
vsi->rx_rings[i] = ring;
1005410071
}
1005510072

@@ -10328,9 +10345,6 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx, int cpu)
1032810345
netif_napi_add(vsi->netdev, &q_vector->napi,
1032910346
i40e_napi_poll, NAPI_POLL_WEIGHT);
1033010347

10331-
q_vector->rx.latency_range = I40E_LOW_LATENCY;
10332-
q_vector->tx.latency_range = I40E_LOW_LATENCY;
10333-
1033410348
/* tie q_vector and vsi together */
1033510349
vsi->q_vectors[v_idx] = q_vector;
1033610350

0 commit comments

Comments
 (0)