i40e: Modify Tx disable wait flow in case of DCB reconfiguration
When DCB TC configuration changes the firmware suspends the port's Tx. Now, as DCB TCs may have changed the PF driver tries to reconfigure the TC configuration of the VSIs it manages. As part of this process it disables the VSI queues but the Tx queue disable will not complete as the port's Tx has been suspended. So, waiting for Tx queues to go to disable state in this flow may lead to detection of Tx queue disable timeout errors. Hence, this patch adds a new PF state so that if a port's Tx is in suspended state the Tx queue disable flow would just put the request for the queue to be disabled and return without waiting for the queue to be actually disabled. Once the VSI(s) TC reconfiguration has been done and driver has called firmware AQC "Resume PF Traffic" the driver checks the Tx queues requested to be disabled are actually disabled before re-enabling them again. Change-ID: If3e03ce4813a4e342dbd5a1eb1d2861e952b7544 Signed-off-by: Neerav Parikh <neerav.parikh@intel.com> Tested-By: Jack Morgan <jack.morgan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Родитель
23cd1f095a
Коммит
69129dc39f
|
@ -146,6 +146,7 @@ enum i40e_state_t {
|
||||||
__I40E_DOWN_REQUESTED,
|
__I40E_DOWN_REQUESTED,
|
||||||
__I40E_FD_FLUSH_REQUESTED,
|
__I40E_FD_FLUSH_REQUESTED,
|
||||||
__I40E_RESET_FAILED,
|
__I40E_RESET_FAILED,
|
||||||
|
__I40E_PORT_TX_SUSPENDED,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum i40e_interrupt_policy {
|
enum i40e_interrupt_policy {
|
||||||
|
|
|
@ -3492,6 +3492,9 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
wr32(hw, I40E_QTX_ENA(pf_q), tx_reg);
|
wr32(hw, I40E_QTX_ENA(pf_q), tx_reg);
|
||||||
|
/* No waiting for the Tx queue to disable */
|
||||||
|
if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* wait for the change to finish */
|
/* wait for the change to finish */
|
||||||
ret = i40e_pf_txq_wait(pf, pf_q, enable);
|
ret = i40e_pf_txq_wait(pf, pf_q, enable);
|
||||||
|
@ -3911,6 +3914,56 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_I40E_DCB
|
||||||
|
/**
|
||||||
|
* i40e_vsi_wait_txq_disabled - Wait for VSI's queues to be disabled
|
||||||
|
* @vsi: the VSI being configured
|
||||||
|
*
|
||||||
|
* This function waits for the given VSI's Tx queues to be disabled.
|
||||||
|
**/
|
||||||
|
static int i40e_vsi_wait_txq_disabled(struct i40e_vsi *vsi)
|
||||||
|
{
|
||||||
|
struct i40e_pf *pf = vsi->back;
|
||||||
|
int i, pf_q, ret;
|
||||||
|
|
||||||
|
pf_q = vsi->base_queue;
|
||||||
|
for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
|
||||||
|
/* Check and wait for the disable status of the queue */
|
||||||
|
ret = i40e_pf_txq_wait(pf, pf_q, false);
|
||||||
|
if (ret) {
|
||||||
|
dev_info(&pf->pdev->dev,
|
||||||
|
"%s: VSI seid %d Tx ring %d disable timeout\n",
|
||||||
|
__func__, vsi->seid, pf_q);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_pf_wait_txq_disabled - Wait for all queues of PF VSIs to be disabled
|
||||||
|
* @pf: the PF
|
||||||
|
*
|
||||||
|
* This function waits for the Tx queues to be in disabled state for all the
|
||||||
|
* VSIs that are managed by this PF.
|
||||||
|
**/
|
||||||
|
static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf)
|
||||||
|
{
|
||||||
|
int v, ret = 0;
|
||||||
|
|
||||||
|
for (v = 0; v < pf->hw.func_caps.num_vsis; v++) {
|
||||||
|
if (pf->vsi[v]) {
|
||||||
|
ret = i40e_vsi_wait_txq_disabled(pf->vsi[v]);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* i40e_dcb_get_num_tc - Get the number of TCs from DCBx config
|
* i40e_dcb_get_num_tc - Get the number of TCs from DCBx config
|
||||||
* @dcbcfg: the corresponding DCBx configuration structure
|
* @dcbcfg: the corresponding DCBx configuration structure
|
||||||
|
@ -5102,6 +5155,7 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
|
||||||
else
|
else
|
||||||
pf->flags &= ~I40E_FLAG_DCB_ENABLED;
|
pf->flags &= ~I40E_FLAG_DCB_ENABLED;
|
||||||
|
|
||||||
|
set_bit(__I40E_PORT_TX_SUSPENDED, &pf->state);
|
||||||
/* Reconfiguration needed quiesce all VSIs */
|
/* Reconfiguration needed quiesce all VSIs */
|
||||||
i40e_pf_quiesce_all_vsi(pf);
|
i40e_pf_quiesce_all_vsi(pf);
|
||||||
|
|
||||||
|
@ -5110,7 +5164,13 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
|
||||||
|
|
||||||
ret = i40e_resume_port_tx(pf);
|
ret = i40e_resume_port_tx(pf);
|
||||||
|
|
||||||
|
clear_bit(__I40E_PORT_TX_SUSPENDED, &pf->state);
|
||||||
/* In case of error no point in resuming VSIs */
|
/* In case of error no point in resuming VSIs */
|
||||||
|
if (ret)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* Wait for the PF's Tx queues to be disabled */
|
||||||
|
ret = i40e_pf_wait_txq_disabled(pf);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
i40e_pf_unquiesce_all_vsi(pf);
|
i40e_pf_unquiesce_all_vsi(pf);
|
||||||
exit:
|
exit:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче