|
4 | 4 | #include "ice.h" |
5 | 5 | #include "ice_lib.h" |
6 | 6 |
|
| 7 | +/** |
| 8 | + * ice_vc_vf_broadcast - Broadcast a message to all VFs on PF |
| 9 | + * @pf: pointer to the PF structure |
| 10 | + * @v_opcode: operation code |
| 11 | + * @v_retval: return value |
| 12 | + * @msg: pointer to the msg buffer |
| 13 | + * @msglen: msg length |
| 14 | + */ |
| 15 | +static void |
| 16 | +ice_vc_vf_broadcast(struct ice_pf *pf, enum virtchnl_ops v_opcode, |
| 17 | + enum ice_status v_retval, u8 *msg, u16 msglen) |
| 18 | +{ |
| 19 | + struct ice_hw *hw = &pf->hw; |
| 20 | + struct ice_vf *vf = pf->vf; |
| 21 | + int i; |
| 22 | + |
| 23 | + for (i = 0; i < pf->num_alloc_vfs; i++, vf++) { |
| 24 | + /* Not all vfs are enabled so skip the ones that are not */ |
| 25 | + if (!test_bit(ICE_VF_STATE_INIT, vf->vf_states) && |
| 26 | + !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) |
| 27 | + continue; |
| 28 | + |
| 29 | + /* Ignore return value on purpose - a given VF may fail, but |
| 30 | + * we need to keep going and send to all of them |
| 31 | + */ |
| 32 | + ice_aq_send_msg_to_vf(hw, vf->vf_id, v_opcode, v_retval, msg, |
| 33 | + msglen, NULL); |
| 34 | + } |
| 35 | +} |
| 36 | + |
7 | 37 | /** |
8 | 38 | * ice_get_vf_vector - get VF interrupt vector register offset |
9 | 39 | * @vf_msix: number of MSIx vector per VF on a PF |
@@ -693,6 +723,97 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr) |
693 | 723 | return true; |
694 | 724 | } |
695 | 725 |
|
| 726 | +/** |
| 727 | + * ice_reset_vf - Reset a particular VF |
| 728 | + * @vf: pointer to the VF structure |
| 729 | + * @is_vflr: true if VFLR was issued, false if not |
| 730 | + * |
| 731 | + * Returns true if the VF is reset, false otherwise. |
| 732 | + */ |
| 733 | +static bool ice_reset_vf(struct ice_vf *vf, bool is_vflr) |
| 734 | +{ |
| 735 | + struct ice_pf *pf = vf->pf; |
| 736 | + struct ice_hw *hw = &pf->hw; |
| 737 | + bool rsd = false; |
| 738 | + u32 reg; |
| 739 | + int i; |
| 740 | + |
| 741 | + /* If the VFs have been disabled, this means something else is |
| 742 | + * resetting the VF, so we shouldn't continue. |
| 743 | + */ |
| 744 | + if (test_and_set_bit(__ICE_VF_DIS, pf->state)) |
| 745 | + return false; |
| 746 | + |
| 747 | + ice_trigger_vf_reset(vf, is_vflr); |
| 748 | + |
| 749 | + if (test_bit(ICE_VF_STATE_ENA, vf->vf_states)) { |
| 750 | + ice_vsi_stop_tx_rings(pf->vsi[vf->lan_vsi_idx], ICE_VF_RESET, |
| 751 | + vf->vf_id); |
| 752 | + ice_vsi_stop_rx_rings(pf->vsi[vf->lan_vsi_idx]); |
| 753 | + clear_bit(ICE_VF_STATE_ENA, vf->vf_states); |
| 754 | + } else { |
| 755 | + /* Call Disable LAN Tx queue AQ call even when queues are not |
| 756 | + * enabled. This is needed for successful completiom of VFR |
| 757 | + */ |
| 758 | + ice_dis_vsi_txq(pf->vsi[vf->lan_vsi_idx]->port_info, 0, |
| 759 | + NULL, NULL, ICE_VF_RESET, vf->vf_id, NULL); |
| 760 | + } |
| 761 | + |
| 762 | + /* poll VPGEN_VFRSTAT reg to make sure |
| 763 | + * that reset is complete |
| 764 | + */ |
| 765 | + for (i = 0; i < 10; i++) { |
| 766 | + /* VF reset requires driver to first reset the VF and then |
| 767 | + * poll the status register to make sure that the reset |
| 768 | + * completed successfully. |
| 769 | + */ |
| 770 | + usleep_range(10000, 20000); |
| 771 | + reg = rd32(hw, VPGEN_VFRSTAT(vf->vf_id)); |
| 772 | + if (reg & VPGEN_VFRSTAT_VFRD_M) { |
| 773 | + rsd = true; |
| 774 | + break; |
| 775 | + } |
| 776 | + } |
| 777 | + |
| 778 | + /* Display a warning if VF didn't manage to reset in time, but need to |
| 779 | + * continue on with the operation. |
| 780 | + */ |
| 781 | + if (!rsd) |
| 782 | + dev_warn(&pf->pdev->dev, "VF reset check timeout on VF %d\n", |
| 783 | + vf->vf_id); |
| 784 | + |
| 785 | + usleep_range(10000, 20000); |
| 786 | + |
| 787 | + /* free VF resources to begin resetting the VSI state */ |
| 788 | + ice_free_vf_res(vf); |
| 789 | + |
| 790 | + ice_cleanup_and_realloc_vf(vf); |
| 791 | + |
| 792 | + ice_flush(hw); |
| 793 | + clear_bit(__ICE_VF_DIS, pf->state); |
| 794 | + |
| 795 | + return true; |
| 796 | +} |
| 797 | + |
| 798 | +/** |
| 799 | + * ice_vc_notify_reset - Send pending reset message to all VFs |
| 800 | + * @pf: pointer to the PF structure |
| 801 | + * |
| 802 | + * indicate a pending reset to all VFs on a given PF |
| 803 | + */ |
| 804 | +void ice_vc_notify_reset(struct ice_pf *pf) |
| 805 | +{ |
| 806 | + struct virtchnl_pf_event pfe; |
| 807 | + |
| 808 | + if (!pf->num_alloc_vfs) |
| 809 | + return; |
| 810 | + |
| 811 | + pfe.event = VIRTCHNL_EVENT_RESET_IMPENDING; |
| 812 | + pfe.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM; |
| 813 | + ice_vc_vf_broadcast(pf, VIRTCHNL_OP_EVENT, ICE_SUCCESS, |
| 814 | + (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); |
| 815 | +} |
| 816 | + |
696 | 817 | /** |
697 | 818 | * ice_alloc_vfs - Allocate and set up VFs resources |
698 | 819 | * @pf: pointer to the PF structure |
@@ -845,3 +966,45 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs) |
845 | 966 |
|
846 | 967 | return 0; |
847 | 968 | } |
| 969 | + |
| 970 | +/** |
| 971 | + * ice_process_vflr_event - Free VF resources via IRQ calls |
| 972 | + * @pf: pointer to the PF structure |
| 973 | + * |
| 974 | + * called from the VLFR IRQ handler to |
| 975 | + * free up VF resources and state variables |
| 976 | + */ |
| 977 | +void ice_process_vflr_event(struct ice_pf *pf) |
| 978 | +{ |
| 979 | + struct ice_hw *hw = &pf->hw; |
| 980 | + int vf_id; |
| 981 | + u32 reg; |
| 982 | + |
| 983 | + if (!test_bit(__ICE_VFLR_EVENT_PENDING, pf->state) || |
| 984 | + !pf->num_alloc_vfs) |
| 985 | + return; |
| 986 | + |
| 987 | + /* Re-enable the VFLR interrupt cause here, before looking for which |
| 988 | + * VF got reset. Otherwise, if another VF gets a reset while the |
| 989 | + * first one is being processed, that interrupt will be lost, and |
| 990 | + * that VF will be stuck in reset forever. |
| 991 | + */ |
| 992 | + reg = rd32(hw, PFINT_OICR_ENA); |
| 993 | + reg |= PFINT_OICR_VFLR_M; |
| 994 | + wr32(hw, PFINT_OICR_ENA, reg); |
| 995 | + ice_flush(hw); |
| 996 | + |
| 997 | + clear_bit(__ICE_VFLR_EVENT_PENDING, pf->state); |
| 998 | + for (vf_id = 0; vf_id < pf->num_alloc_vfs; vf_id++) { |
| 999 | + struct ice_vf *vf = &pf->vf[vf_id]; |
| 1000 | + u32 reg_idx, bit_idx; |
| 1001 | + |
| 1002 | + reg_idx = (hw->func_caps.vf_base_id + vf_id) / 32; |
| 1003 | + bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32; |
| 1004 | + /* read GLGEN_VFLRSTAT register to find out the flr VFs */ |
| 1005 | + reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx)); |
| 1006 | + if (reg & BIT(bit_idx)) |
| 1007 | + /* GLGEN_VFLRSTAT bit will be cleared in ice_reset_vf */ |
| 1008 | + ice_reset_vf(vf, true); |
| 1009 | + } |
| 1010 | +} |
0 commit comments