diff options
author | Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> | 2019-02-28 18:25:48 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-05-02 03:57:44 -0400 |
commit | bb87ee0efb7396d79ba5f37ff8e8721d01c87d4a (patch) | |
tree | f4cbd3f588e0409d949f865d44d5cc990bf535d1 /drivers/net/ethernet/intel/ice | |
parent | f76c4b571feea8eb03184d8ba0ee45f98fff47ff (diff) |
ice: Create framework for VSI queue context
This patch introduces a framework to store queue specific information
in VSI queue contexts. Currently VSI queue context (represented by
struct ice_q_ctx) only has q_handle as a member. In future patches,
this structure will be updated to hold queue specific information.
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')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.c | 62 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 99 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_sched.c | 54 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_switch.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 4 |
7 files changed, 205 insertions, 56 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 2937c6be1aee..dce07882f7e1 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c | |||
@@ -2791,10 +2791,35 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) | |||
2791 | } | 2791 | } |
2792 | 2792 | ||
2793 | /** | 2793 | /** |
2794 | * ice_get_lan_q_ctx - get the LAN queue context for the given VSI and TC | ||
2795 | * @hw: pointer to the HW struct | ||
2796 | * @vsi_handle: software VSI handle | ||
2797 | * @tc: TC number | ||
2798 | * @q_handle: software queue handle | ||
2799 | */ | ||
2800 | static struct ice_q_ctx * | ||
2801 | ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle) | ||
2802 | { | ||
2803 | struct ice_vsi_ctx *vsi; | ||
2804 | struct ice_q_ctx *q_ctx; | ||
2805 | |||
2806 | vsi = ice_get_vsi_ctx(hw, vsi_handle); | ||
2807 | if (!vsi) | ||
2808 | return NULL; | ||
2809 | if (q_handle >= vsi->num_lan_q_entries[tc]) | ||
2810 | return NULL; | ||
2811 | if (!vsi->lan_q_ctx[tc]) | ||
2812 | return NULL; | ||
2813 | q_ctx = vsi->lan_q_ctx[tc]; | ||
2814 | return &q_ctx[q_handle]; | ||
2815 | } | ||
2816 | |||
2817 | /** | ||
2794 | * ice_ena_vsi_txq | 2818 | * ice_ena_vsi_txq |
2795 | * @pi: port information structure | 2819 | * @pi: port information structure |
2796 | * @vsi_handle: software VSI handle | 2820 | * @vsi_handle: software VSI handle |
2797 | * @tc: TC number | 2821 | * @tc: TC number |
2822 | * @q_handle: software queue handle | ||
2798 | * @num_qgrps: Number of added queue groups | 2823 | * @num_qgrps: Number of added queue groups |
2799 | * @buf: list of queue groups to be added | 2824 | * @buf: list of queue groups to be added |
2800 | * @buf_size: size of buffer for indirect command | 2825 | * @buf_size: size of buffer for indirect command |
@@ -2803,12 +2828,13 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) | |||
2803 | * This function adds one LAN queue | 2828 | * This function adds one LAN queue |
2804 | */ | 2829 | */ |
2805 | enum ice_status | 2830 | enum ice_status |
2806 | ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps, | 2831 | ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle, |
2807 | struct ice_aqc_add_tx_qgrp *buf, u16 buf_size, | 2832 | u8 num_qgrps, struct ice_aqc_add_tx_qgrp *buf, u16 buf_size, |
2808 | struct ice_sq_cd *cd) | 2833 | struct ice_sq_cd *cd) |
2809 | { | 2834 | { |
2810 | struct ice_aqc_txsched_elem_data node = { 0 }; | 2835 | struct ice_aqc_txsched_elem_data node = { 0 }; |
2811 | struct ice_sched_node *parent; | 2836 | struct ice_sched_node *parent; |
2837 | struct ice_q_ctx *q_ctx; | ||
2812 | enum ice_status status; | 2838 | enum ice_status status; |
2813 | struct ice_hw *hw; | 2839 | struct ice_hw *hw; |
2814 | 2840 | ||
@@ -2825,6 +2851,14 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps, | |||
2825 | 2851 | ||
2826 | mutex_lock(&pi->sched_lock); | 2852 | mutex_lock(&pi->sched_lock); |
2827 | 2853 | ||
2854 | q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handle); | ||
2855 | if (!q_ctx) { | ||
2856 | ice_debug(hw, ICE_DBG_SCHED, "Enaq: invalid queue handle %d\n", | ||
2857 | q_handle); | ||
2858 | status = ICE_ERR_PARAM; | ||
2859 | goto ena_txq_exit; | ||
2860 | } | ||
2861 | |||
2828 | /* find a parent node */ | 2862 | /* find a parent node */ |
2829 | parent = ice_sched_get_free_qparent(pi, vsi_handle, tc, | 2863 | parent = ice_sched_get_free_qparent(pi, vsi_handle, tc, |
2830 | ICE_SCHED_NODE_OWNER_LAN); | 2864 | ICE_SCHED_NODE_OWNER_LAN); |
@@ -2851,7 +2885,7 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps, | |||
2851 | /* add the LAN queue */ | 2885 | /* add the LAN queue */ |
2852 | status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd); | 2886 | status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd); |
2853 | if (status) { | 2887 | if (status) { |
2854 | ice_debug(hw, ICE_DBG_SCHED, "enable Q %d failed %d\n", | 2888 | ice_debug(hw, ICE_DBG_SCHED, "enable queue %d failed %d\n", |
2855 | le16_to_cpu(buf->txqs[0].txq_id), | 2889 | le16_to_cpu(buf->txqs[0].txq_id), |
2856 | hw->adminq.sq_last_status); | 2890 | hw->adminq.sq_last_status); |
2857 | goto ena_txq_exit; | 2891 | goto ena_txq_exit; |
@@ -2859,6 +2893,7 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps, | |||
2859 | 2893 | ||
2860 | node.node_teid = buf->txqs[0].q_teid; | 2894 | node.node_teid = buf->txqs[0].q_teid; |
2861 | node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF; | 2895 | node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF; |
2896 | q_ctx->q_handle = q_handle; | ||
2862 | 2897 | ||
2863 | /* add a leaf node into schduler tree queue layer */ | 2898 | /* add a leaf node into schduler tree queue layer */ |
2864 | status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node); | 2899 | status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node); |
@@ -2871,7 +2906,10 @@ ena_txq_exit: | |||
2871 | /** | 2906 | /** |
2872 | * ice_dis_vsi_txq | 2907 | * ice_dis_vsi_txq |
2873 | * @pi: port information structure | 2908 | * @pi: port information structure |
2909 | * @vsi_handle: software VSI handle | ||
2910 | * @tc: TC number | ||
2874 | * @num_queues: number of queues | 2911 | * @num_queues: number of queues |
2912 | * @q_handles: pointer to software queue handle array | ||
2875 | * @q_ids: pointer to the q_id array | 2913 | * @q_ids: pointer to the q_id array |
2876 | * @q_teids: pointer to queue node teids | 2914 | * @q_teids: pointer to queue node teids |
2877 | * @rst_src: if called due to reset, specifies the reset source | 2915 | * @rst_src: if called due to reset, specifies the reset source |
@@ -2881,12 +2919,14 @@ ena_txq_exit: | |||
2881 | * This function removes queues and their corresponding nodes in SW DB | 2919 | * This function removes queues and their corresponding nodes in SW DB |
2882 | */ | 2920 | */ |
2883 | enum ice_status | 2921 | enum ice_status |
2884 | ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids, | 2922 | ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues, |
2885 | u32 *q_teids, enum ice_disq_rst_src rst_src, u16 vmvf_num, | 2923 | u16 *q_handles, u16 *q_ids, u32 *q_teids, |
2924 | enum ice_disq_rst_src rst_src, u16 vmvf_num, | ||
2886 | struct ice_sq_cd *cd) | 2925 | struct ice_sq_cd *cd) |
2887 | { | 2926 | { |
2888 | enum ice_status status = ICE_ERR_DOES_NOT_EXIST; | 2927 | enum ice_status status = ICE_ERR_DOES_NOT_EXIST; |
2889 | struct ice_aqc_dis_txq_item qg_list; | 2928 | struct ice_aqc_dis_txq_item qg_list; |
2929 | struct ice_q_ctx *q_ctx; | ||
2890 | u16 i; | 2930 | u16 i; |
2891 | 2931 | ||
2892 | if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) | 2932 | if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY) |
@@ -2909,6 +2949,17 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids, | |||
2909 | node = ice_sched_find_node_by_teid(pi->root, q_teids[i]); | 2949 | node = ice_sched_find_node_by_teid(pi->root, q_teids[i]); |
2910 | if (!node) | 2950 | if (!node) |
2911 | continue; | 2951 | continue; |
2952 | q_ctx = ice_get_lan_q_ctx(pi->hw, vsi_handle, tc, q_handles[i]); | ||
2953 | if (!q_ctx) { | ||
2954 | ice_debug(pi->hw, ICE_DBG_SCHED, "invalid queue handle%d\n", | ||
2955 | q_handles[i]); | ||
2956 | continue; | ||
2957 | } | ||
2958 | if (q_ctx->q_handle != q_handles[i]) { | ||
2959 | ice_debug(pi->hw, ICE_DBG_SCHED, "Err:handles %d %d\n", | ||
2960 | q_ctx->q_handle, q_handles[i]); | ||
2961 | continue; | ||
2962 | } | ||
2912 | qg_list.parent_teid = node->info.parent_teid; | 2963 | qg_list.parent_teid = node->info.parent_teid; |
2913 | qg_list.num_qs = 1; | 2964 | qg_list.num_qs = 1; |
2914 | qg_list.q_id[0] = cpu_to_le16(q_ids[i]); | 2965 | qg_list.q_id[0] = cpu_to_le16(q_ids[i]); |
@@ -2919,6 +2970,7 @@ ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids, | |||
2919 | if (status) | 2970 | if (status) |
2920 | break; | 2971 | break; |
2921 | ice_free_sched_node(pi, node); | 2972 | ice_free_sched_node(pi, node); |
2973 | q_ctx->q_handle = ICE_INVAL_Q_HANDLE; | ||
2922 | } | 2974 | } |
2923 | mutex_unlock(&pi->sched_lock); | 2975 | mutex_unlock(&pi->sched_lock); |
2924 | return status; | 2976 | return status; |
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h index faefc45e4a1e..f1ddebf45231 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.h +++ b/drivers/net/ethernet/intel/ice/ice_common.h | |||
@@ -99,15 +99,16 @@ ice_aq_set_port_id_led(struct ice_port_info *pi, bool is_orig_mode, | |||
99 | struct ice_sq_cd *cd); | 99 | struct ice_sq_cd *cd); |
100 | 100 | ||
101 | enum ice_status | 101 | enum ice_status |
102 | ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids, | 102 | ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues, |
103 | u32 *q_teids, enum ice_disq_rst_src rst_src, u16 vmvf_num, | 103 | u16 *q_handle, u16 *q_ids, u32 *q_teids, |
104 | struct ice_sq_cd *cmd_details); | 104 | enum ice_disq_rst_src rst_src, u16 vmvf_num, |
105 | struct ice_sq_cd *cd); | ||
105 | enum ice_status | 106 | enum ice_status |
106 | ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap, | 107 | ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap, |
107 | u16 *max_lanqs); | 108 | u16 *max_lanqs); |
108 | enum ice_status | 109 | enum ice_status |
109 | ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps, | 110 | ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle, |
110 | struct ice_aqc_add_tx_qgrp *buf, u16 buf_size, | 111 | u8 num_qgrps, struct ice_aqc_add_tx_qgrp *buf, u16 buf_size, |
111 | struct ice_sq_cd *cd); | 112 | struct ice_sq_cd *cd); |
112 | enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle); | 113 | enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle); |
113 | void ice_replay_post(struct ice_hw *hw); | 114 | void ice_replay_post(struct ice_hw *hw); |
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index f31129e4e9cf..fa8ebd8a10ce 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c | |||
@@ -1715,8 +1715,8 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings, int offset) | |||
1715 | rings[q_idx]->tail = | 1715 | rings[q_idx]->tail = |
1716 | pf->hw.hw_addr + QTX_COMM_DBELL(pf_q); | 1716 | pf->hw.hw_addr + QTX_COMM_DBELL(pf_q); |
1717 | status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, | 1717 | status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc, |
1718 | num_q_grps, qg_buf, buf_len, | 1718 | i, num_q_grps, qg_buf, |
1719 | NULL); | 1719 | buf_len, NULL); |
1720 | if (status) { | 1720 | if (status) { |
1721 | dev_err(&vsi->back->pdev->dev, | 1721 | dev_err(&vsi->back->pdev->dev, |
1722 | "Failed to set LAN Tx queue context, error: %d\n", | 1722 | "Failed to set LAN Tx queue context, error: %d\n", |
@@ -2033,10 +2033,10 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, | |||
2033 | { | 2033 | { |
2034 | struct ice_pf *pf = vsi->back; | 2034 | struct ice_pf *pf = vsi->back; |
2035 | struct ice_hw *hw = &pf->hw; | 2035 | struct ice_hw *hw = &pf->hw; |
2036 | int tc, q_idx = 0, err = 0; | ||
2037 | u16 *q_ids, *q_handles, i; | ||
2036 | enum ice_status status; | 2038 | enum ice_status status; |
2037 | u32 *q_teids, val; | 2039 | u32 *q_teids, val; |
2038 | u16 *q_ids, i; | ||
2039 | int err = 0; | ||
2040 | 2040 | ||
2041 | if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) | 2041 | if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) |
2042 | return -EINVAL; | 2042 | return -EINVAL; |
@@ -2053,50 +2053,71 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, | |||
2053 | goto err_alloc_q_ids; | 2053 | goto err_alloc_q_ids; |
2054 | } | 2054 | } |
2055 | 2055 | ||
2056 | /* set up the Tx queue list to be disabled */ | 2056 | q_handles = devm_kcalloc(&pf->pdev->dev, vsi->num_txq, |
2057 | ice_for_each_txq(vsi, i) { | 2057 | sizeof(*q_handles), GFP_KERNEL); |
2058 | u16 v_idx; | 2058 | if (!q_handles) { |
2059 | err = -ENOMEM; | ||
2060 | goto err_alloc_q_handles; | ||
2061 | } | ||
2059 | 2062 | ||
2060 | if (!rings || !rings[i] || !rings[i]->q_vector) { | 2063 | /* set up the Tx queue list to be disabled for each enabled TC */ |
2061 | err = -EINVAL; | 2064 | ice_for_each_traffic_class(tc) { |
2062 | goto err_out; | 2065 | if (!(vsi->tc_cfg.ena_tc & BIT(tc))) |
2063 | } | 2066 | break; |
2067 | |||
2068 | for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) { | ||
2069 | u16 v_idx; | ||
2070 | |||
2071 | if (!rings || !rings[i] || !rings[i]->q_vector) { | ||
2072 | err = -EINVAL; | ||
2073 | goto err_out; | ||
2074 | } | ||
2064 | 2075 | ||
2065 | q_ids[i] = vsi->txq_map[i + offset]; | 2076 | q_ids[i] = vsi->txq_map[q_idx + offset]; |
2066 | q_teids[i] = rings[i]->txq_teid; | 2077 | q_teids[i] = rings[q_idx]->txq_teid; |
2078 | q_handles[i] = i; | ||
2067 | 2079 | ||
2068 | /* clear cause_ena bit for disabled queues */ | 2080 | /* clear cause_ena bit for disabled queues */ |
2069 | val = rd32(hw, QINT_TQCTL(rings[i]->reg_idx)); | 2081 | val = rd32(hw, QINT_TQCTL(rings[i]->reg_idx)); |
2070 | val &= ~QINT_TQCTL_CAUSE_ENA_M; | 2082 | val &= ~QINT_TQCTL_CAUSE_ENA_M; |
2071 | wr32(hw, QINT_TQCTL(rings[i]->reg_idx), val); | 2083 | wr32(hw, QINT_TQCTL(rings[i]->reg_idx), val); |
2072 | 2084 | ||
2073 | /* software is expected to wait for 100 ns */ | 2085 | /* software is expected to wait for 100 ns */ |
2074 | ndelay(100); | 2086 | ndelay(100); |
2075 | 2087 | ||
2076 | /* trigger a software interrupt for the vector associated to | 2088 | /* trigger a software interrupt for the vector |
2077 | * the queue to schedule NAPI handler | 2089 | * associated to the queue to schedule NAPI handler |
2090 | */ | ||
2091 | v_idx = rings[i]->q_vector->v_idx; | ||
2092 | wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx), | ||
2093 | GLINT_DYN_CTL_SWINT_TRIG_M | | ||
2094 | GLINT_DYN_CTL_INTENA_MSK_M); | ||
2095 | q_idx++; | ||
2096 | } | ||
2097 | status = ice_dis_vsi_txq(vsi->port_info, vsi->idx, tc, | ||
2098 | vsi->num_txq, q_handles, q_ids, | ||
2099 | q_teids, rst_src, rel_vmvf_num, NULL); | ||
2100 | |||
2101 | /* if the disable queue command was exercised during an active | ||
2102 | * reset flow, ICE_ERR_RESET_ONGOING is returned. This is not | ||
2103 | * an error as the reset operation disables queues at the | ||
2104 | * hardware level anyway. | ||
2078 | */ | 2105 | */ |
2079 | v_idx = rings[i]->q_vector->v_idx; | 2106 | if (status == ICE_ERR_RESET_ONGOING) { |
2080 | wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx), | 2107 | dev_dbg(&pf->pdev->dev, |
2081 | GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M); | 2108 | "Reset in progress. LAN Tx queues already disabled\n"); |
2082 | } | 2109 | } else if (status) { |
2083 | status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids, | 2110 | dev_err(&pf->pdev->dev, |
2084 | rst_src, rel_vmvf_num, NULL); | 2111 | "Failed to disable LAN Tx queues, error: %d\n", |
2085 | /* if the disable queue command was exercised during an active reset | 2112 | status); |
2086 | * flow, ICE_ERR_RESET_ONGOING is returned. This is not an error as | 2113 | err = -ENODEV; |
2087 | * the reset operation disables queues at the hardware level anyway. | 2114 | } |
2088 | */ | ||
2089 | if (status == ICE_ERR_RESET_ONGOING) { | ||
2090 | dev_info(&pf->pdev->dev, | ||
2091 | "Reset in progress. LAN Tx queues already disabled\n"); | ||
2092 | } else if (status) { | ||
2093 | dev_err(&pf->pdev->dev, | ||
2094 | "Failed to disable LAN Tx queues, error: %d\n", | ||
2095 | status); | ||
2096 | err = -ENODEV; | ||
2097 | } | 2115 | } |
2098 | 2116 | ||
2099 | err_out: | 2117 | err_out: |
2118 | devm_kfree(&pf->pdev->dev, q_handles); | ||
2119 | |||
2120 | err_alloc_q_handles: | ||
2100 | devm_kfree(&pf->pdev->dev, q_ids); | 2121 | devm_kfree(&pf->pdev->dev, q_ids); |
2101 | 2122 | ||
2102 | err_alloc_q_ids: | 2123 | err_alloc_q_ids: |
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index 124feaf0e730..8d49f83be7a5 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c | |||
@@ -533,6 +533,50 @@ ice_sched_suspend_resume_elems(struct ice_hw *hw, u8 num_nodes, u32 *node_teids, | |||
533 | } | 533 | } |
534 | 534 | ||
535 | /** | 535 | /** |
536 | * ice_alloc_lan_q_ctx - allocate LAN queue contexts for the given VSI and TC | ||
537 | * @hw: pointer to the HW struct | ||
538 | * @vsi_handle: VSI handle | ||
539 | * @tc: TC number | ||
540 | * @new_numqs: number of queues | ||
541 | */ | ||
542 | static enum ice_status | ||
543 | ice_alloc_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 new_numqs) | ||
544 | { | ||
545 | struct ice_vsi_ctx *vsi_ctx; | ||
546 | struct ice_q_ctx *q_ctx; | ||
547 | |||
548 | vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); | ||
549 | if (!vsi_ctx) | ||
550 | return ICE_ERR_PARAM; | ||
551 | /* allocate LAN queue contexts */ | ||
552 | if (!vsi_ctx->lan_q_ctx[tc]) { | ||
553 | vsi_ctx->lan_q_ctx[tc] = devm_kcalloc(ice_hw_to_dev(hw), | ||
554 | new_numqs, | ||
555 | sizeof(*q_ctx), | ||
556 | GFP_KERNEL); | ||
557 | if (!vsi_ctx->lan_q_ctx[tc]) | ||
558 | return ICE_ERR_NO_MEMORY; | ||
559 | vsi_ctx->num_lan_q_entries[tc] = new_numqs; | ||
560 | return 0; | ||
561 | } | ||
562 | /* num queues are increased, update the queue contexts */ | ||
563 | if (new_numqs > vsi_ctx->num_lan_q_entries[tc]) { | ||
564 | u16 prev_num = vsi_ctx->num_lan_q_entries[tc]; | ||
565 | |||
566 | q_ctx = devm_kcalloc(ice_hw_to_dev(hw), new_numqs, | ||
567 | sizeof(*q_ctx), GFP_KERNEL); | ||
568 | if (!q_ctx) | ||
569 | return ICE_ERR_NO_MEMORY; | ||
570 | memcpy(q_ctx, vsi_ctx->lan_q_ctx[tc], | ||
571 | prev_num * sizeof(*q_ctx)); | ||
572 | devm_kfree(ice_hw_to_dev(hw), vsi_ctx->lan_q_ctx[tc]); | ||
573 | vsi_ctx->lan_q_ctx[tc] = q_ctx; | ||
574 | vsi_ctx->num_lan_q_entries[tc] = new_numqs; | ||
575 | } | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | /** | ||
536 | * ice_sched_clear_agg - clears the aggregator related information | 580 | * ice_sched_clear_agg - clears the aggregator related information |
537 | * @hw: pointer to the hardware structure | 581 | * @hw: pointer to the hardware structure |
538 | * | 582 | * |
@@ -1403,14 +1447,14 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle, | |||
1403 | if (!vsi_ctx) | 1447 | if (!vsi_ctx) |
1404 | return ICE_ERR_PARAM; | 1448 | return ICE_ERR_PARAM; |
1405 | 1449 | ||
1406 | if (owner == ICE_SCHED_NODE_OWNER_LAN) | 1450 | prev_numqs = vsi_ctx->sched.max_lanq[tc]; |
1407 | prev_numqs = vsi_ctx->sched.max_lanq[tc]; | ||
1408 | else | ||
1409 | return ICE_ERR_PARAM; | ||
1410 | |||
1411 | /* num queues are not changed or less than the previous number */ | 1451 | /* num queues are not changed or less than the previous number */ |
1412 | if (new_numqs <= prev_numqs) | 1452 | if (new_numqs <= prev_numqs) |
1413 | return status; | 1453 | return status; |
1454 | status = ice_alloc_lan_q_ctx(hw, vsi_handle, tc, new_numqs); | ||
1455 | if (status) | ||
1456 | return status; | ||
1457 | |||
1414 | if (new_numqs) | 1458 | if (new_numqs) |
1415 | ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes); | 1459 | ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes); |
1416 | /* Keep the max number of queue configuration all the time. Update the | 1460 | /* Keep the max number of queue configuration all the time. Update the |
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index ad6bb0fce5d1..81f44939c859 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c | |||
@@ -329,6 +329,27 @@ ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) | |||
329 | } | 329 | } |
330 | 330 | ||
331 | /** | 331 | /** |
332 | * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs | ||
333 | * @hw: pointer to the HW struct | ||
334 | * @vsi_handle: VSI handle | ||
335 | */ | ||
336 | static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) | ||
337 | { | ||
338 | struct ice_vsi_ctx *vsi; | ||
339 | u8 i; | ||
340 | |||
341 | vsi = ice_get_vsi_ctx(hw, vsi_handle); | ||
342 | if (!vsi) | ||
343 | return; | ||
344 | ice_for_each_traffic_class(i) { | ||
345 | if (vsi->lan_q_ctx[i]) { | ||
346 | devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]); | ||
347 | vsi->lan_q_ctx[i] = NULL; | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /** | ||
332 | * ice_clear_vsi_ctx - clear the VSI context entry | 353 | * ice_clear_vsi_ctx - clear the VSI context entry |
333 | * @hw: pointer to the HW struct | 354 | * @hw: pointer to the HW struct |
334 | * @vsi_handle: VSI handle | 355 | * @vsi_handle: VSI handle |
@@ -341,6 +362,7 @@ static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) | |||
341 | 362 | ||
342 | vsi = ice_get_vsi_ctx(hw, vsi_handle); | 363 | vsi = ice_get_vsi_ctx(hw, vsi_handle); |
343 | if (vsi) { | 364 | if (vsi) { |
365 | ice_clear_vsi_q_ctx(hw, vsi_handle); | ||
344 | devm_kfree(ice_hw_to_dev(hw), vsi); | 366 | devm_kfree(ice_hw_to_dev(hw), vsi); |
345 | hw->vsi_ctx[vsi_handle] = NULL; | 367 | hw->vsi_ctx[vsi_handle] = NULL; |
346 | } | 368 | } |
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h index 64a2fecfce20..88eb4be4d5a4 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.h +++ b/drivers/net/ethernet/intel/ice/ice_switch.h | |||
@@ -9,6 +9,13 @@ | |||
9 | #define ICE_SW_CFG_MAX_BUF_LEN 2048 | 9 | #define ICE_SW_CFG_MAX_BUF_LEN 2048 |
10 | #define ICE_DFLT_VSI_INVAL 0xff | 10 | #define ICE_DFLT_VSI_INVAL 0xff |
11 | #define ICE_VSI_INVAL_ID 0xffff | 11 | #define ICE_VSI_INVAL_ID 0xffff |
12 | #define ICE_INVAL_Q_HANDLE 0xFFFF | ||
13 | #define ICE_INVAL_Q_HANDLE 0xFFFF | ||
14 | |||
15 | /* VSI queue context structure */ | ||
16 | struct ice_q_ctx { | ||
17 | u16 q_handle; | ||
18 | }; | ||
12 | 19 | ||
13 | /* VSI context structure for add/get/update/free operations */ | 20 | /* VSI context structure for add/get/update/free operations */ |
14 | struct ice_vsi_ctx { | 21 | struct ice_vsi_ctx { |
@@ -20,6 +27,8 @@ struct ice_vsi_ctx { | |||
20 | struct ice_sched_vsi_info sched; | 27 | struct ice_sched_vsi_info sched; |
21 | u8 alloc_from_pool; | 28 | u8 alloc_from_pool; |
22 | u8 vf_num; | 29 | u8 vf_num; |
30 | u16 num_lan_q_entries[ICE_MAX_TRAFFIC_CLASS]; | ||
31 | struct ice_q_ctx *lan_q_ctx[ICE_MAX_TRAFFIC_CLASS]; | ||
23 | }; | 32 | }; |
24 | 33 | ||
25 | enum ice_sw_fwd_act_type { | 34 | enum ice_sw_fwd_act_type { |
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index e562ea15b79b..789b6f10b381 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | |||
@@ -996,8 +996,8 @@ static bool ice_reset_vf(struct ice_vf *vf, bool is_vflr) | |||
996 | /* Call Disable LAN Tx queue AQ call even when queues are not | 996 | /* Call Disable LAN Tx queue AQ call even when queues are not |
997 | * enabled. This is needed for successful completiom of VFR | 997 | * enabled. This is needed for successful completiom of VFR |
998 | */ | 998 | */ |
999 | ice_dis_vsi_txq(vsi->port_info, 0, NULL, NULL, ICE_VF_RESET, | 999 | ice_dis_vsi_txq(vsi->port_info, vsi->idx, 0, 0, NULL, NULL, |
1000 | vf->vf_id, NULL); | 1000 | NULL, ICE_VF_RESET, vf->vf_id, NULL); |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | hw = &pf->hw; | 1003 | hw = &pf->hw; |