diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 116 |
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 | ||
1377 | skip_req_irq: | 1394 | skip_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 | */ | ||
1885 | static 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 | */ |
1866 | static int ice_init_interrupt_scheme(struct ice_pf *pf) | 1905 | static 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; |
1897 | static 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, |