aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_main.c
diff options
context:
space:
mode:
authorBrett Creeley <brett.creeley@intel.com>2019-02-08 15:50:34 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2019-02-25 11:56:01 -0500
commit0e04e8e14b558c84a7c7a64d3e94655f5071eef5 (patch)
tree579e884e2305a913fe1722f021302da0657ad3dd /drivers/net/ethernet/intel/ice/ice_main.c
parentf9264dd687f8d3f9104c9900f8f3e5e419f27c55 (diff)
ice: fix issue where host reboots on unload when iommu=on
Currently if the kernel has the intel_iommu=on parameter set, on some platforms removing the driver causes a system reboot. In initialization we associate the control queue interrupts with the pf->hw_oicr_idx and enable the interrupts by setting the CAUSE_ENA bit. The problem comes on teardown because we are not clearing the CAUSE_ENA bit for the control queues, but the vector at pf->hw_oicr_idx (miscellaneous interrupt vector) gets disabled. Fix this by clearing the CAUSE_ENA bit in the appropriate control queue registers on when freeing the miscellaneous interrupt vector. Also, move the call to ice_free_irq_msix_misc() to after ice_deinit_sw() in ice_remove() because ice_deinit_sw() makes an AQ call, but ice_free_irq_msix_misc() disables the miscellaneous vector and it's associated interrupts. Also, create two small helper functions to enable and disable the control queue interrupts respectively. Signed-off-by: Brett Creeley <brett.creeley@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_main.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index aff348e42562..fb04a5ebdc0b 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1356,14 +1356,39 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
1356} 1356}
1357 1357
1358/** 1358/**
1359 * ice_dis_ctrlq_interrupts - disable control queue interrupts
1360 * @hw: pointer to HW structure
1361 */
1362static void ice_dis_ctrlq_interrupts(struct ice_hw *hw)
1363{
1364 /* disable Admin queue Interrupt causes */
1365 wr32(hw, PFINT_FW_CTL,
1366 rd32(hw, PFINT_FW_CTL) & ~PFINT_FW_CTL_CAUSE_ENA_M);
1367
1368 /* disable Mailbox queue Interrupt causes */
1369 wr32(hw, PFINT_MBX_CTL,
1370 rd32(hw, PFINT_MBX_CTL) & ~PFINT_MBX_CTL_CAUSE_ENA_M);
1371
1372 /* disable Control queue Interrupt causes */
1373 wr32(hw, PFINT_OICR_CTL,
1374 rd32(hw, PFINT_OICR_CTL) & ~PFINT_OICR_CTL_CAUSE_ENA_M);
1375
1376 ice_flush(hw);
1377}
1378
1379/**
1359 * ice_free_irq_msix_misc - Unroll misc vector setup 1380 * ice_free_irq_msix_misc - Unroll misc vector setup
1360 * @pf: board private structure 1381 * @pf: board private structure
1361 */ 1382 */
1362static void ice_free_irq_msix_misc(struct ice_pf *pf) 1383static void ice_free_irq_msix_misc(struct ice_pf *pf)
1363{ 1384{
1385 struct ice_hw *hw = &pf->hw;
1386
1387 ice_dis_ctrlq_interrupts(hw);
1388
1364 /* disable OICR interrupt */ 1389 /* disable OICR interrupt */
1365 wr32(&pf->hw, PFINT_OICR_ENA, 0); 1390 wr32(hw, PFINT_OICR_ENA, 0);
1366 ice_flush(&pf->hw); 1391 ice_flush(hw);
1367 1392
1368 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) { 1393 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) {
1369 synchronize_irq(pf->msix_entries[pf->sw_oicr_idx].vector); 1394 synchronize_irq(pf->msix_entries[pf->sw_oicr_idx].vector);
@@ -1378,6 +1403,32 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
1378} 1403}
1379 1404
1380/** 1405/**
1406 * ice_ena_ctrlq_interrupts - enable control queue interrupts
1407 * @hw: pointer to HW structure
1408 * @v_idx: HW vector index to associate the control queue interrupts with
1409 */
1410static void ice_ena_ctrlq_interrupts(struct ice_hw *hw, u16 v_idx)
1411{
1412 u32 val;
1413
1414 val = ((v_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
1415 PFINT_OICR_CTL_CAUSE_ENA_M);
1416 wr32(hw, PFINT_OICR_CTL, val);
1417
1418 /* enable Admin queue Interrupt causes */
1419 val = ((v_idx & PFINT_FW_CTL_MSIX_INDX_M) |
1420 PFINT_FW_CTL_CAUSE_ENA_M);
1421 wr32(hw, PFINT_FW_CTL, val);
1422
1423 /* enable Mailbox queue Interrupt causes */
1424 val = ((v_idx & PFINT_MBX_CTL_MSIX_INDX_M) |
1425 PFINT_MBX_CTL_CAUSE_ENA_M);
1426 wr32(hw, PFINT_MBX_CTL, val);
1427
1428 ice_flush(hw);
1429}
1430
1431/**
1381 * ice_req_irq_msix_misc - Setup the misc vector to handle non queue events 1432 * ice_req_irq_msix_misc - Setup the misc vector to handle non queue events
1382 * @pf: board private structure 1433 * @pf: board private structure
1383 * 1434 *
@@ -1389,7 +1440,6 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
1389{ 1440{
1390 struct ice_hw *hw = &pf->hw; 1441 struct ice_hw *hw = &pf->hw;
1391 int oicr_idx, err = 0; 1442 int oicr_idx, err = 0;
1392 u32 val;
1393 1443
1394 if (!pf->int_name[0]) 1444 if (!pf->int_name[0])
1395 snprintf(pf->int_name, sizeof(pf->int_name) - 1, "%s-%s:misc", 1445 snprintf(pf->int_name, sizeof(pf->int_name) - 1, "%s-%s:misc",
@@ -1438,20 +1488,7 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
1438skip_req_irq: 1488skip_req_irq:
1439 ice_ena_misc_vector(pf); 1489 ice_ena_misc_vector(pf);
1440 1490
1441 val = ((pf->hw_oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) | 1491 ice_ena_ctrlq_interrupts(hw, pf->hw_oicr_idx);
1442 PFINT_OICR_CTL_CAUSE_ENA_M);
1443 wr32(hw, PFINT_OICR_CTL, val);
1444
1445 /* This enables Admin queue Interrupt causes */
1446 val = ((pf->hw_oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
1447 PFINT_FW_CTL_CAUSE_ENA_M);
1448 wr32(hw, PFINT_FW_CTL, val);
1449
1450 /* This enables Mailbox queue Interrupt causes */
1451 val = ((pf->hw_oicr_idx & PFINT_MBX_CTL_MSIX_INDX_M) |
1452 PFINT_MBX_CTL_CAUSE_ENA_M);
1453 wr32(hw, PFINT_MBX_CTL, val);
1454
1455 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx), 1492 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx),
1456 ITR_REG_ALIGN(ICE_ITR_8K) >> ICE_ITR_GRAN_S); 1493 ITR_REG_ALIGN(ICE_ITR_8K) >> ICE_ITR_GRAN_S);
1457 1494