i40e: clear all queues and interrupts
Per a recent HW designer comment, this code is for ripping through the queues and interrupts to fully disable them on driver init, specifically to help clean up after a PXE or other early boot activity. Change-ID: I32ed452021a1c2b06dace1969976f882a37b9741 Signed-off-by: Shannon Nelson <shannon.nelson@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Родитель
4346940b96
Коммит
838d41d92a
|
@ -810,6 +810,99 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_clear_hw - clear out any left over hw state
|
||||
* @hw: pointer to the hw struct
|
||||
*
|
||||
* Clear queues and interrupts, typically called at init time,
|
||||
* but after the capabilities have been found so we know how many
|
||||
* queues and msix vectors have been allocated.
|
||||
**/
|
||||
void i40e_clear_hw(struct i40e_hw *hw)
|
||||
{
|
||||
u32 num_queues, base_queue;
|
||||
u32 num_pf_int;
|
||||
u32 num_vf_int;
|
||||
u32 num_vfs;
|
||||
u32 i, j;
|
||||
u32 val;
|
||||
u32 eol = 0x7ff;
|
||||
|
||||
/* get number of interrupts, queues, and vfs */
|
||||
val = rd32(hw, I40E_GLPCI_CNF2);
|
||||
num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
|
||||
I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
|
||||
num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
|
||||
I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
|
||||
|
||||
val = rd32(hw, I40E_PFLAN_QALLOC);
|
||||
base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
|
||||
I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
|
||||
j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
|
||||
I40E_PFLAN_QALLOC_LASTQ_SHIFT;
|
||||
if (val & I40E_PFLAN_QALLOC_VALID_MASK)
|
||||
num_queues = (j - base_queue) + 1;
|
||||
else
|
||||
num_queues = 0;
|
||||
|
||||
val = rd32(hw, I40E_PF_VT_PFALLOC);
|
||||
i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
|
||||
I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
|
||||
j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
|
||||
I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
|
||||
if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
|
||||
num_vfs = (j - i) + 1;
|
||||
else
|
||||
num_vfs = 0;
|
||||
|
||||
/* stop all the interrupts */
|
||||
wr32(hw, I40E_PFINT_ICR0_ENA, 0);
|
||||
val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
|
||||
for (i = 0; i < num_pf_int - 2; i++)
|
||||
wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
|
||||
|
||||
/* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
|
||||
val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
|
||||
wr32(hw, I40E_PFINT_LNKLST0, val);
|
||||
for (i = 0; i < num_pf_int - 2; i++)
|
||||
wr32(hw, I40E_PFINT_LNKLSTN(i), val);
|
||||
val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
|
||||
for (i = 0; i < num_vfs; i++)
|
||||
wr32(hw, I40E_VPINT_LNKLST0(i), val);
|
||||
for (i = 0; i < num_vf_int - 2; i++)
|
||||
wr32(hw, I40E_VPINT_LNKLSTN(i), val);
|
||||
|
||||
/* warn the HW of the coming Tx disables */
|
||||
for (i = 0; i < num_queues; i++) {
|
||||
u32 abs_queue_idx = base_queue + i;
|
||||
u32 reg_block = 0;
|
||||
|
||||
if (abs_queue_idx >= 128) {
|
||||
reg_block = abs_queue_idx / 128;
|
||||
abs_queue_idx %= 128;
|
||||
}
|
||||
|
||||
val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
|
||||
val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
|
||||
val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
|
||||
val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
|
||||
|
||||
wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
|
||||
}
|
||||
udelay(400);
|
||||
|
||||
/* stop all the queues */
|
||||
for (i = 0; i < num_queues; i++) {
|
||||
wr32(hw, I40E_QINT_TQCTL(i), 0);
|
||||
wr32(hw, I40E_QTX_ENA(i), 0);
|
||||
wr32(hw, I40E_QINT_RQCTL(i), 0);
|
||||
wr32(hw, I40E_QRX_ENA(i), 0);
|
||||
}
|
||||
|
||||
/* short wait for all queue disables to settle */
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_clear_pxe_mode - clear pxe operations mode
|
||||
* @hw: pointer to the hw struct
|
||||
|
|
|
@ -8636,6 +8636,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
}
|
||||
|
||||
/* Reset here to make sure all is clean and to define PF 'n' */
|
||||
i40e_clear_hw(hw);
|
||||
err = i40e_pf_reset(hw);
|
||||
if (err) {
|
||||
dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
|
||||
|
|
|
@ -217,6 +217,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
|
|||
/* i40e_common */
|
||||
i40e_status i40e_init_shared_code(struct i40e_hw *hw);
|
||||
i40e_status i40e_pf_reset(struct i40e_hw *hw);
|
||||
void i40e_clear_hw(struct i40e_hw *hw);
|
||||
void i40e_clear_pxe_mode(struct i40e_hw *hw);
|
||||
bool i40e_get_link_status(struct i40e_hw *hw);
|
||||
i40e_status i40e_get_mac_addr(struct i40e_hw *hw,
|
||||
|
|
Загрузка…
Ссылка в новой задаче