diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index df20d68c92ab..6ba82337d017 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c | |||
@@ -342,6 +342,71 @@ void ice_vsi_delete(struct ice_vsi *vsi) | |||
342 | } | 342 | } |
343 | 343 | ||
344 | /** | 344 | /** |
345 | * ice_vsi_free_arrays - clean up VSI resources | ||
346 | * @vsi: pointer to VSI being cleared | ||
347 | * @free_qvectors: bool to specify if q_vectors should be deallocated | ||
348 | */ | ||
349 | void ice_vsi_free_arrays(struct ice_vsi *vsi, bool free_qvectors) | ||
350 | { | ||
351 | struct ice_pf *pf = vsi->back; | ||
352 | |||
353 | /* free the ring and vector containers */ | ||
354 | if (free_qvectors && vsi->q_vectors) { | ||
355 | devm_kfree(&pf->pdev->dev, vsi->q_vectors); | ||
356 | vsi->q_vectors = NULL; | ||
357 | } | ||
358 | if (vsi->tx_rings) { | ||
359 | devm_kfree(&pf->pdev->dev, vsi->tx_rings); | ||
360 | vsi->tx_rings = NULL; | ||
361 | } | ||
362 | if (vsi->rx_rings) { | ||
363 | devm_kfree(&pf->pdev->dev, vsi->rx_rings); | ||
364 | vsi->rx_rings = NULL; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * ice_vsi_clear - clean up and deallocate the provided VSI | ||
370 | * @vsi: pointer to VSI being cleared | ||
371 | * | ||
372 | * This deallocates the VSI's queue resources, removes it from the PF's | ||
373 | * VSI array if necessary, and deallocates the VSI | ||
374 | * | ||
375 | * Returns 0 on success, negative on failure | ||
376 | */ | ||
377 | int ice_vsi_clear(struct ice_vsi *vsi) | ||
378 | { | ||
379 | struct ice_pf *pf = NULL; | ||
380 | |||
381 | if (!vsi) | ||
382 | return 0; | ||
383 | |||
384 | if (!vsi->back) | ||
385 | return -EINVAL; | ||
386 | |||
387 | pf = vsi->back; | ||
388 | |||
389 | if (!pf->vsi[vsi->idx] || pf->vsi[vsi->idx] != vsi) { | ||
390 | dev_dbg(&pf->pdev->dev, "vsi does not exist at pf->vsi[%d]\n", | ||
391 | vsi->idx); | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | mutex_lock(&pf->sw_mutex); | ||
396 | /* updates the PF for this cleared VSI */ | ||
397 | |||
398 | pf->vsi[vsi->idx] = NULL; | ||
399 | if (vsi->idx < pf->next_vsi) | ||
400 | pf->next_vsi = vsi->idx; | ||
401 | |||
402 | ice_vsi_free_arrays(vsi, true); | ||
403 | mutex_unlock(&pf->sw_mutex); | ||
404 | devm_kfree(&pf->pdev->dev, vsi); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | /** | ||
345 | * ice_msix_clean_rings - MSIX mode Interrupt Handler | 410 | * ice_msix_clean_rings - MSIX mode Interrupt Handler |
346 | * @irq: interrupt number | 411 | * @irq: interrupt number |
347 | * @data: pointer to a q_vector | 412 | * @data: pointer to a q_vector |
@@ -701,6 +766,60 @@ err_out: | |||
701 | } | 766 | } |
702 | 767 | ||
703 | /** | 768 | /** |
769 | * ice_vsi_map_rings_to_vectors - Map VSI rings to interrupt vectors | ||
770 | * @vsi: the VSI being configured | ||
771 | * | ||
772 | * This function maps descriptor rings to the queue-specific vectors allotted | ||
773 | * through the MSI-X enabling code. On a constrained vector budget, we map Tx | ||
774 | * and Rx rings to the vector as "efficiently" as possible. | ||
775 | */ | ||
776 | void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi) | ||
777 | { | ||
778 | int q_vectors = vsi->num_q_vectors; | ||
779 | int tx_rings_rem, rx_rings_rem; | ||
780 | int v_id; | ||
781 | |||
782 | /* initially assigning remaining rings count to VSIs num queue value */ | ||
783 | tx_rings_rem = vsi->num_txq; | ||
784 | rx_rings_rem = vsi->num_rxq; | ||
785 | |||
786 | for (v_id = 0; v_id < q_vectors; v_id++) { | ||
787 | struct ice_q_vector *q_vector = vsi->q_vectors[v_id]; | ||
788 | int tx_rings_per_v, rx_rings_per_v, q_id, q_base; | ||
789 | |||
790 | /* Tx rings mapping to vector */ | ||
791 | tx_rings_per_v = DIV_ROUND_UP(tx_rings_rem, q_vectors - v_id); | ||
792 | q_vector->num_ring_tx = tx_rings_per_v; | ||
793 | q_vector->tx.ring = NULL; | ||
794 | q_base = vsi->num_txq - tx_rings_rem; | ||
795 | |||
796 | for (q_id = q_base; q_id < (q_base + tx_rings_per_v); q_id++) { | ||
797 | struct ice_ring *tx_ring = vsi->tx_rings[q_id]; | ||
798 | |||
799 | tx_ring->q_vector = q_vector; | ||
800 | tx_ring->next = q_vector->tx.ring; | ||
801 | q_vector->tx.ring = tx_ring; | ||
802 | } | ||
803 | tx_rings_rem -= tx_rings_per_v; | ||
804 | |||
805 | /* Rx rings mapping to vector */ | ||
806 | rx_rings_per_v = DIV_ROUND_UP(rx_rings_rem, q_vectors - v_id); | ||
807 | q_vector->num_ring_rx = rx_rings_per_v; | ||
808 | q_vector->rx.ring = NULL; | ||
809 | q_base = vsi->num_rxq - rx_rings_rem; | ||
810 | |||
811 | for (q_id = q_base; q_id < (q_base + rx_rings_per_v); q_id++) { | ||
812 | struct ice_ring *rx_ring = vsi->rx_rings[q_id]; | ||
813 | |||
814 | rx_ring->q_vector = q_vector; | ||
815 | rx_ring->next = q_vector->rx.ring; | ||
816 | q_vector->rx.ring = rx_ring; | ||
817 | } | ||
818 | rx_rings_rem -= rx_rings_per_v; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | /** | ||
704 | * ice_add_mac_to_list - Add a mac address filter entry to the list | 823 | * ice_add_mac_to_list - Add a mac address filter entry to the list |
705 | * @vsi: the VSI to be forwarded to | 824 | * @vsi: the VSI to be forwarded to |
706 | * @add_list: pointer to the list which contains MAC filter entries | 825 | * @add_list: pointer to the list which contains MAC filter entries |
@@ -1386,6 +1505,20 @@ void ice_vsi_free_rx_rings(struct ice_vsi *vsi) | |||
1386 | } | 1505 | } |
1387 | 1506 | ||
1388 | /** | 1507 | /** |
1508 | * ice_vsi_close - Shut down a VSI | ||
1509 | * @vsi: the VSI being shut down | ||
1510 | */ | ||
1511 | void ice_vsi_close(struct ice_vsi *vsi) | ||
1512 | { | ||
1513 | if (!test_and_set_bit(__ICE_DOWN, vsi->state)) | ||
1514 | ice_down(vsi); | ||
1515 | |||
1516 | ice_vsi_free_irq(vsi); | ||
1517 | ice_vsi_free_tx_rings(vsi); | ||
1518 | ice_vsi_free_rx_rings(vsi); | ||
1519 | } | ||
1520 | |||
1521 | /** | ||
1389 | * ice_free_res - free a block of resources | 1522 | * ice_free_res - free a block of resources |
1390 | * @res: pointer to the resource | 1523 | * @res: pointer to the resource |
1391 | * @index: starting index previously returned by ice_get_res | 1524 | * @index: starting index previously returned by ice_get_res |