diff options
| -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; |
