aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_main.c
diff options
context:
space:
mode:
authorPreethi Banala <preethi.banala@intel.com>2018-09-19 20:23:16 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-02 10:16:19 -0400
commiteb0208ec42d319bc09fead0e1afe2bc0c28aeca0 (patch)
tree0af2e51b50e4ab0f45e35fa4fcb090386f071267 /drivers/net/ethernet/intel/ice/ice_main.c
parent5755143dd18d3b7fa97b419d18d9bb4764b7b46f (diff)
ice: Split irq_tracker into sw_irq_tracker and hw_irq_tracker
For the PF driver, when mapping interrupts to queues, we need to request IRQs from the kernel and we also have to allocate interrupts from the device. Similarly, when the VF driver (iavf.ko) initializes, it requests the kernel IRQs that it needs but it can't directly allocate interrupts in the device. Instead, it sends a mailbox message to the ice driver, which then allocates interrupts in the device on the VF driver's behalf. Currently both these cases end up having to reserve entries in pf->irq_tracker but irq_tracker itself is sized based on how many vectors the PF driver needs. Under the right circumstances, the VF driver can fail to get entries in irq_tracker, which will result in the VF driver failing probe. To fix this, sw_irq_tracker and hw_irq_tracker are introduced. The sw_irq_tracker tracks only the PF's IRQ request and doesn't play any role in VF init. hw_irq_tracker represents the device's interrupt space. When interrupts have to be allocated in the device for either PF or VF, hw_irq_tracker will be looked up to see if the device has run out of interrupts. Signed-off-by: Preethi Banala <preethi.banala@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.c116
1 files changed, 81 insertions, 35 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index bb42ee643b77..d9f30d15ad65 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -95,7 +95,7 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf)
95 /* Trigger sw interrupt to revive the queue */ 95 /* Trigger sw interrupt to revive the queue */
96 v_idx = tx_ring->q_vector->v_idx; 96 v_idx = tx_ring->q_vector->v_idx;
97 wr32(&vsi->back->hw, 97 wr32(&vsi->back->hw,
98 GLINT_DYN_CTL(vsi->base_vector + v_idx), 98 GLINT_DYN_CTL(vsi->hw_base_vector + v_idx),
99 (itr << GLINT_DYN_CTL_ITR_INDX_S) | 99 (itr << GLINT_DYN_CTL_ITR_INDX_S) |
100 GLINT_DYN_CTL_SWINT_TRIG_M | 100 GLINT_DYN_CTL_SWINT_TRIG_M |
101 GLINT_DYN_CTL_INTENA_MSK_M); 101 GLINT_DYN_CTL_INTENA_MSK_M);
@@ -1122,7 +1122,7 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename)
1122{ 1122{
1123 int q_vectors = vsi->num_q_vectors; 1123 int q_vectors = vsi->num_q_vectors;
1124 struct ice_pf *pf = vsi->back; 1124 struct ice_pf *pf = vsi->back;
1125 int base = vsi->base_vector; 1125 int base = vsi->sw_base_vector;
1126 int rx_int_idx = 0; 1126 int rx_int_idx = 0;
1127 int tx_int_idx = 0; 1127 int tx_int_idx = 0;
1128 int vector, err; 1128 int vector, err;
@@ -1203,7 +1203,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
1203 wr32(hw, PFINT_OICR_ENA, val); 1203 wr32(hw, PFINT_OICR_ENA, val);
1204 1204
1205 /* SW_ITR_IDX = 0, but don't change INTENA */ 1205 /* SW_ITR_IDX = 0, but don't change INTENA */
1206 wr32(hw, GLINT_DYN_CTL(pf->oicr_idx), 1206 wr32(hw, GLINT_DYN_CTL(pf->hw_oicr_idx),
1207 GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M); 1207 GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
1208} 1208}
1209 1209
@@ -1321,12 +1321,15 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
1321 ice_flush(&pf->hw); 1321 ice_flush(&pf->hw);
1322 1322
1323 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) { 1323 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) {
1324 synchronize_irq(pf->msix_entries[pf->oicr_idx].vector); 1324 synchronize_irq(pf->msix_entries[pf->sw_oicr_idx].vector);
1325 devm_free_irq(&pf->pdev->dev, 1325 devm_free_irq(&pf->pdev->dev,
1326 pf->msix_entries[pf->oicr_idx].vector, pf); 1326 pf->msix_entries[pf->sw_oicr_idx].vector, pf);
1327 } 1327 }
1328 1328
1329 ice_free_res(pf->irq_tracker, pf->oicr_idx, ICE_RES_MISC_VEC_ID); 1329 pf->num_avail_sw_msix += 1;
1330 ice_free_res(pf->sw_irq_tracker, pf->sw_oicr_idx, ICE_RES_MISC_VEC_ID);
1331 pf->num_avail_hw_msix += 1;
1332 ice_free_res(pf->hw_irq_tracker, pf->hw_oicr_idx, ICE_RES_MISC_VEC_ID);
1330} 1333}
1331 1334
1332/** 1335/**
@@ -1356,39 +1359,53 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
1356 if (ice_is_reset_in_progress(pf->state)) 1359 if (ice_is_reset_in_progress(pf->state))
1357 goto skip_req_irq; 1360 goto skip_req_irq;
1358 1361
1359 /* reserve one vector in irq_tracker for misc interrupts */ 1362 /* reserve one vector in sw_irq_tracker for misc interrupts */
1360 oicr_idx = ice_get_res(pf, pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID); 1363 oicr_idx = ice_get_res(pf, pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
1361 if (oicr_idx < 0) 1364 if (oicr_idx < 0)
1362 return oicr_idx; 1365 return oicr_idx;
1363 1366
1364 pf->oicr_idx = oicr_idx; 1367 pf->num_avail_sw_msix -= 1;
1368 pf->sw_oicr_idx = oicr_idx;
1369
1370 /* reserve one vector in hw_irq_tracker for misc interrupts */
1371 oicr_idx = ice_get_res(pf, pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
1372 if (oicr_idx < 0) {
1373 ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
1374 pf->num_avail_sw_msix += 1;
1375 return oicr_idx;
1376 }
1377 pf->num_avail_hw_msix -= 1;
1378 pf->hw_oicr_idx = oicr_idx;
1365 1379
1366 err = devm_request_irq(&pf->pdev->dev, 1380 err = devm_request_irq(&pf->pdev->dev,
1367 pf->msix_entries[pf->oicr_idx].vector, 1381 pf->msix_entries[pf->sw_oicr_idx].vector,
1368 ice_misc_intr, 0, pf->int_name, pf); 1382 ice_misc_intr, 0, pf->int_name, pf);
1369 if (err) { 1383 if (err) {
1370 dev_err(&pf->pdev->dev, 1384 dev_err(&pf->pdev->dev,
1371 "devm_request_irq for %s failed: %d\n", 1385 "devm_request_irq for %s failed: %d\n",
1372 pf->int_name, err); 1386 pf->int_name, err);
1373 ice_free_res(pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID); 1387 ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
1388 pf->num_avail_sw_msix += 1;
1389 ice_free_res(pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
1390 pf->num_avail_hw_msix += 1;
1374 return err; 1391 return err;
1375 } 1392 }
1376 1393
1377skip_req_irq: 1394skip_req_irq:
1378 ice_ena_misc_vector(pf); 1395 ice_ena_misc_vector(pf);
1379 1396
1380 val = ((pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) | 1397 val = ((pf->hw_oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
1381 PFINT_OICR_CTL_CAUSE_ENA_M); 1398 PFINT_OICR_CTL_CAUSE_ENA_M);
1382 wr32(hw, PFINT_OICR_CTL, val); 1399 wr32(hw, PFINT_OICR_CTL, val);
1383 1400
1384 /* This enables Admin queue Interrupt causes */ 1401 /* This enables Admin queue Interrupt causes */
1385 val = ((pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) | 1402 val = ((pf->hw_oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
1386 PFINT_FW_CTL_CAUSE_ENA_M); 1403 PFINT_FW_CTL_CAUSE_ENA_M);
1387 wr32(hw, PFINT_FW_CTL, val); 1404 wr32(hw, PFINT_FW_CTL, val);
1388 1405
1389 itr_gran = hw->itr_gran_200; 1406 itr_gran = hw->itr_gran_200;
1390 1407
1391 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_idx), 1408 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx),
1392 ITR_TO_REG(ICE_ITR_8K, itr_gran)); 1409 ITR_TO_REG(ICE_ITR_8K, itr_gran));
1393 1410
1394 ice_flush(hw); 1411 ice_flush(hw);
@@ -1797,6 +1814,7 @@ static int ice_ena_msix_range(struct ice_pf *pf)
1797 /* reserve vectors for LAN traffic */ 1814 /* reserve vectors for LAN traffic */
1798 pf->num_lan_msix = min_t(int, num_online_cpus(), v_left); 1815 pf->num_lan_msix = min_t(int, num_online_cpus(), v_left);
1799 v_budget += pf->num_lan_msix; 1816 v_budget += pf->num_lan_msix;
1817 v_left -= pf->num_lan_msix;
1800 1818
1801 pf->msix_entries = devm_kcalloc(&pf->pdev->dev, v_budget, 1819 pf->msix_entries = devm_kcalloc(&pf->pdev->dev, v_budget,
1802 sizeof(struct msix_entry), GFP_KERNEL); 1820 sizeof(struct msix_entry), GFP_KERNEL);
@@ -1824,10 +1842,11 @@ static int ice_ena_msix_range(struct ice_pf *pf)
1824 "not enough vectors. requested = %d, obtained = %d\n", 1842 "not enough vectors. requested = %d, obtained = %d\n",
1825 v_budget, v_actual); 1843 v_budget, v_actual);
1826 if (v_actual >= (pf->num_lan_msix + 1)) { 1844 if (v_actual >= (pf->num_lan_msix + 1)) {
1827 pf->num_avail_msix = v_actual - (pf->num_lan_msix + 1); 1845 pf->num_avail_sw_msix = v_actual -
1846 (pf->num_lan_msix + 1);
1828 } else if (v_actual >= 2) { 1847 } else if (v_actual >= 2) {
1829 pf->num_lan_msix = 1; 1848 pf->num_lan_msix = 1;
1830 pf->num_avail_msix = v_actual - 2; 1849 pf->num_avail_sw_msix = v_actual - 2;
1831 } else { 1850 } else {
1832 pci_disable_msix(pf->pdev); 1851 pci_disable_msix(pf->pdev);
1833 err = -ERANGE; 1852 err = -ERANGE;
@@ -1860,12 +1879,32 @@ static void ice_dis_msix(struct ice_pf *pf)
1860} 1879}
1861 1880
1862/** 1881/**
1882 * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme
1883 * @pf: board private structure
1884 */
1885static void ice_clear_interrupt_scheme(struct ice_pf *pf)
1886{
1887 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
1888 ice_dis_msix(pf);
1889
1890 if (pf->sw_irq_tracker) {
1891 devm_kfree(&pf->pdev->dev, pf->sw_irq_tracker);
1892 pf->sw_irq_tracker = NULL;
1893 }
1894
1895 if (pf->hw_irq_tracker) {
1896 devm_kfree(&pf->pdev->dev, pf->hw_irq_tracker);
1897 pf->hw_irq_tracker = NULL;
1898 }
1899}
1900
1901/**
1863 * ice_init_interrupt_scheme - Determine proper interrupt scheme 1902 * ice_init_interrupt_scheme - Determine proper interrupt scheme
1864 * @pf: board private structure to initialize 1903 * @pf: board private structure to initialize
1865 */ 1904 */
1866static int ice_init_interrupt_scheme(struct ice_pf *pf) 1905static int ice_init_interrupt_scheme(struct ice_pf *pf)
1867{ 1906{
1868 int vectors = 0; 1907 int vectors = 0, hw_vectors = 0;
1869 ssize_t size; 1908 ssize_t size;
1870 1909
1871 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) 1910 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
@@ -1879,30 +1918,31 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf)
1879 /* set up vector assignment tracking */ 1918 /* set up vector assignment tracking */
1880 size = sizeof(struct ice_res_tracker) + (sizeof(u16) * vectors); 1919 size = sizeof(struct ice_res_tracker) + (sizeof(u16) * vectors);
1881 1920
1882 pf->irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL); 1921 pf->sw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL);
1883 if (!pf->irq_tracker) { 1922 if (!pf->sw_irq_tracker) {
1884 ice_dis_msix(pf); 1923 ice_dis_msix(pf);
1885 return -ENOMEM; 1924 return -ENOMEM;
1886 } 1925 }
1887 1926
1888 pf->irq_tracker->num_entries = vectors; 1927 /* populate SW interrupts pool with number of OS granted IRQs. */
1928 pf->num_avail_sw_msix = vectors;
1929 pf->sw_irq_tracker->num_entries = vectors;
1889 1930
1890 return 0; 1931 /* set up HW vector assignment tracking */
1891} 1932 hw_vectors = pf->hw.func_caps.common_cap.num_msix_vectors;
1933 size = sizeof(struct ice_res_tracker) + (sizeof(u16) * hw_vectors);
1892 1934
1893/** 1935 pf->hw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL);
1894 * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme 1936 if (!pf->hw_irq_tracker) {
1895 * @pf: board private structure 1937 ice_clear_interrupt_scheme(pf);
1896 */ 1938 return -ENOMEM;
1897static void ice_clear_interrupt_scheme(struct ice_pf *pf)
1898{
1899 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
1900 ice_dis_msix(pf);
1901
1902 if (pf->irq_tracker) {
1903 devm_kfree(&pf->pdev->dev, pf->irq_tracker);
1904 pf->irq_tracker = NULL;
1905 } 1939 }
1940
1941 /* populate HW interrupts pool with number of HW supported irqs. */
1942 pf->num_avail_hw_msix = hw_vectors;
1943 pf->hw_irq_tracker->num_entries = hw_vectors;
1944
1945 return 0;
1906} 1946}
1907 1947
1908/** 1948/**
@@ -3213,6 +3253,12 @@ static void ice_rebuild(struct ice_pf *pf)
3213 if (err) 3253 if (err)
3214 goto err_sched_init_port; 3254 goto err_sched_init_port;
3215 3255
3256 /* reset search_hint of irq_trackers to 0 since interrupts are
3257 * reclaimed and could be allocated from beginning during VSI rebuild
3258 */
3259 pf->sw_irq_tracker->search_hint = 0;
3260 pf->hw_irq_tracker->search_hint = 0;
3261
3216 err = ice_vsi_rebuild_all(pf); 3262 err = ice_vsi_rebuild_all(pf);
3217 if (err) { 3263 if (err) {
3218 dev_err(dev, "ice_vsi_rebuild_all failed\n"); 3264 dev_err(dev, "ice_vsi_rebuild_all failed\n");
@@ -3610,7 +3656,7 @@ static void ice_tx_timeout(struct net_device *netdev)
3610 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) 3656 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
3611 val = rd32(&pf->hw, 3657 val = rd32(&pf->hw,
3612 GLINT_DYN_CTL(tx_ring->q_vector->v_idx + 3658 GLINT_DYN_CTL(tx_ring->q_vector->v_idx +
3613 tx_ring->vsi->base_vector - 1)); 3659 tx_ring->vsi->hw_base_vector));
3614 3660
3615 netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n", 3661 netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n",
3616 vsi->vsi_num, hung_queue, tx_ring->next_to_clean, 3662 vsi->vsi_num, hung_queue, tx_ring->next_to_clean,