Skip to content

Commit 4dc926d

Browse files
bcreeley13Jeff Kirsher
authored andcommitted
ice: Fix Tx timeout when link is toggled on a VF's interface
Currently if the iavf is loaded and a VF link transitions from up to down to up again a Tx timeout will be triggered. This happens because Tx/Rx queue interrupts are only enabled when receiving the VIRTCHNL_OP_CONFIG_MAP_IRQ message, which happens on reset or initial iavf driver load, but not when bringing link up. This is problematic because they are disabled on the VIRTCHNL_OP_DISABLE_QUEUES message, which is part of bringing a VF's link down. However, they are not enabled on the VIRTCHNL_OP_ENABLE_QUEUES message, which is part of bringing a VF's link up. Fix this by re-enabling the VF's Rx and Tx queue interrupts when they were previously configured. This is done by first checking to make sure the previous value in QINT_[R|T]QCTL.MSIX_INDX is not 0, which is used to represent the OICR in the VF's interrupt space. If the MSIX_INDX is non-zero then enable the interrupt by setting the QINT_[R|T]CTL.CAUSE_ENA bit to 1. Signed-off-by: Brett Creeley <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 7438a3b commit 4dc926d

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,52 @@ static bool ice_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs)
23162316
return true;
23172317
}
23182318

2319+
/**
2320+
* ice_vf_ena_txq_interrupt - enable Tx queue interrupt via QINT_TQCTL
2321+
* @vsi: VSI of the VF to configure
2322+
* @q_idx: VF queue index used to determine the queue in the PF's space
2323+
*/
2324+
static void ice_vf_ena_txq_interrupt(struct ice_vsi *vsi, u32 q_idx)
2325+
{
2326+
struct ice_hw *hw = &vsi->back->hw;
2327+
u32 pfq = vsi->txq_map[q_idx];
2328+
u32 reg;
2329+
2330+
reg = rd32(hw, QINT_TQCTL(pfq));
2331+
2332+
/* MSI-X index 0 in the VF's space is always for the OICR, which means
2333+
* this is most likely a poll mode VF driver, so don't enable an
2334+
* interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP
2335+
*/
2336+
if (!(reg & QINT_TQCTL_MSIX_INDX_M))
2337+
return;
2338+
2339+
wr32(hw, QINT_TQCTL(pfq), reg | QINT_TQCTL_CAUSE_ENA_M);
2340+
}
2341+
2342+
/**
2343+
* ice_vf_ena_rxq_interrupt - enable Tx queue interrupt via QINT_RQCTL
2344+
* @vsi: VSI of the VF to configure
2345+
* @q_idx: VF queue index used to determine the queue in the PF's space
2346+
*/
2347+
static void ice_vf_ena_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx)
2348+
{
2349+
struct ice_hw *hw = &vsi->back->hw;
2350+
u32 pfq = vsi->rxq_map[q_idx];
2351+
u32 reg;
2352+
2353+
reg = rd32(hw, QINT_RQCTL(pfq));
2354+
2355+
/* MSI-X index 0 in the VF's space is always for the OICR, which means
2356+
* this is most likely a poll mode VF driver, so don't enable an
2357+
* interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP
2358+
*/
2359+
if (!(reg & QINT_RQCTL_MSIX_INDX_M))
2360+
return;
2361+
2362+
wr32(hw, QINT_RQCTL(pfq), reg | QINT_RQCTL_CAUSE_ENA_M);
2363+
}
2364+
23192365
/**
23202366
* ice_vc_ena_qs_msg
23212367
* @vf: pointer to the VF info
@@ -2376,6 +2422,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
23762422
goto error_param;
23772423
}
23782424

2425+
ice_vf_ena_rxq_interrupt(vsi, vf_q_id);
23792426
set_bit(vf_q_id, vf->rxq_ena);
23802427
}
23812428

@@ -2391,6 +2438,7 @@ static int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
23912438
if (test_bit(vf_q_id, vf->txq_ena))
23922439
continue;
23932440

2441+
ice_vf_ena_txq_interrupt(vsi, vf_q_id);
23942442
set_bit(vf_q_id, vf->txq_ena);
23952443
}
23962444

0 commit comments

Comments
 (0)