mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
i40e/i40evf: Add support for writeback on ITR feature for X722
X722 fixes an issue from X710 where TX descriptor WB would not happen if the interrupts were disabled. In order for the write backs to happen a bit needs to be set in the dynamic interrupt control register called WB_ON_ITR. With this feature, the SW driver need not arm SW interrupts to work around the issue in X710. Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com> Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
e25d00b87b
commit
8e0764b4d6
7 changed files with 72 additions and 16 deletions
|
@ -560,6 +560,7 @@ struct i40e_q_vector {
|
|||
cpumask_t affinity_mask;
|
||||
struct rcu_head rcu; /* to avoid race with update stats on free */
|
||||
char name[I40E_INT_NAME_STR_LEN];
|
||||
bool arm_wb_state;
|
||||
} ____cacheline_internodealigned_in_smp;
|
||||
|
||||
/* lan device */
|
||||
|
|
|
@ -7071,6 +7071,8 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
|
|||
tx_ring->count = vsi->num_desc;
|
||||
tx_ring->size = 0;
|
||||
tx_ring->dcb_tc = 0;
|
||||
if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)
|
||||
tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
|
||||
vsi->tx_rings[i] = tx_ring;
|
||||
|
||||
rx_ring = &tx_ring[1];
|
||||
|
|
|
@ -853,15 +853,40 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
|
|||
**/
|
||||
static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
|
||||
{
|
||||
u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
|
||||
I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */
|
||||
I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK |
|
||||
I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK;
|
||||
/* allow 00 to be written to the index */
|
||||
u16 flags = q_vector->tx.ring[0].flags;
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1),
|
||||
val);
|
||||
if (flags & I40E_TXR_FLAGS_WB_ON_ITR) {
|
||||
u32 val;
|
||||
|
||||
if (q_vector->arm_wb_state)
|
||||
return;
|
||||
|
||||
val = I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK;
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_PFINT_DYN_CTLN(q_vector->v_idx +
|
||||
vsi->base_vector - 1),
|
||||
val);
|
||||
q_vector->arm_wb_state = true;
|
||||
} else if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
|
||||
u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
|
||||
I40E_PFINT_DYN_CTLN_ITR_INDX_MASK | /* set noitr */
|
||||
I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK |
|
||||
I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK;
|
||||
/* allow 00 to be written to the index */
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_PFINT_DYN_CTLN(q_vector->v_idx +
|
||||
vsi->base_vector - 1), val);
|
||||
} else {
|
||||
u32 val = I40E_PFINT_DYN_CTL0_INTENA_MASK |
|
||||
I40E_PFINT_DYN_CTL0_ITR_INDX_MASK | /* set noitr */
|
||||
I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK |
|
||||
I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK;
|
||||
/* allow 00 to be written to the index */
|
||||
|
||||
wr32(&vsi->back->hw, I40E_PFINT_DYN_CTL0, val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1918,6 +1943,9 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
|
|||
return budget;
|
||||
}
|
||||
|
||||
if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR)
|
||||
q_vector->arm_wb_state = false;
|
||||
|
||||
/* Work is done so exit the polling mode and re-enable the interrupt */
|
||||
napi_complete(napi);
|
||||
if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
|
||||
|
|
|
@ -265,6 +265,8 @@ struct i40e_ring {
|
|||
bool ring_active; /* is ring online or not */
|
||||
bool arm_wb; /* do something to arm write back */
|
||||
|
||||
u16 flags;
|
||||
#define I40E_TXR_FLAGS_WB_ON_ITR BIT(0)
|
||||
/* stats structs */
|
||||
struct i40e_queue_stats stats;
|
||||
struct u64_stats_sync syncp;
|
||||
|
|
|
@ -366,15 +366,32 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
|
|||
**/
|
||||
static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
|
||||
{
|
||||
u32 val = I40E_VFINT_DYN_CTLN_INTENA_MASK |
|
||||
I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | /* set noitr */
|
||||
I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK |
|
||||
I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK;
|
||||
/* allow 00 to be written to the index */
|
||||
u16 flags = q_vector->tx.ring[0].flags;
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_VFINT_DYN_CTLN1(q_vector->v_idx + vsi->base_vector - 1),
|
||||
val);
|
||||
if (flags & I40E_TXR_FLAGS_WB_ON_ITR) {
|
||||
u32 val;
|
||||
|
||||
if (q_vector->arm_wb_state)
|
||||
return;
|
||||
|
||||
val = I40E_VFINT_DYN_CTLN1_WB_ON_ITR_MASK;
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_VFINT_DYN_CTLN1(q_vector->v_idx +
|
||||
vsi->base_vector - 1),
|
||||
val);
|
||||
q_vector->arm_wb_state = true;
|
||||
} else {
|
||||
u32 val = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
|
||||
I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK | /* set noitr */
|
||||
I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK |
|
||||
I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK;
|
||||
/* allow 00 to be written to the index */
|
||||
|
||||
wr32(&vsi->back->hw,
|
||||
I40E_VFINT_DYN_CTLN1(q_vector->v_idx +
|
||||
vsi->base_vector - 1), val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1372,6 +1389,9 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)
|
|||
return budget;
|
||||
}
|
||||
|
||||
if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR)
|
||||
q_vector->arm_wb_state = false;
|
||||
|
||||
/* Work is done so exit the polling mode and re-enable the interrupt */
|
||||
napi_complete(napi);
|
||||
i40e_update_enable_itr(vsi, q_vector);
|
||||
|
|
|
@ -262,6 +262,8 @@ struct i40e_ring {
|
|||
bool ring_active; /* is ring online or not */
|
||||
bool arm_wb; /* do something to arm write back */
|
||||
|
||||
u16 flags;
|
||||
#define I40E_TXR_FLAGS_WB_ON_ITR BIT(0)
|
||||
/* stats structs */
|
||||
struct i40e_queue_stats stats;
|
||||
struct u64_stats_sync syncp;
|
||||
|
|
|
@ -117,6 +117,7 @@ struct i40e_q_vector {
|
|||
u8 num_ringpairs; /* total number of ring pairs in vector */
|
||||
int v_idx; /* vector index in list */
|
||||
char name[IFNAMSIZ + 9];
|
||||
bool arm_wb_state;
|
||||
cpumask_var_t affinity_mask;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue