xref: /linux/drivers/net/ethernet/intel/ice/virt/queues.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
11948b867SPrzemek Kitszel // SPDX-License-Identifier: GPL-2.0
21948b867SPrzemek Kitszel /* Copyright (C) 2022, Intel Corporation. */
31948b867SPrzemek Kitszel 
41948b867SPrzemek Kitszel #include "virtchnl.h"
5c762b0a5SPrzemek Kitszel #include "queues.h"
61948b867SPrzemek Kitszel #include "ice_vf_lib_private.h"
71948b867SPrzemek Kitszel #include "ice.h"
81948b867SPrzemek Kitszel #include "ice_base.h"
91948b867SPrzemek Kitszel #include "ice_lib.h"
101948b867SPrzemek Kitszel 
111948b867SPrzemek Kitszel /**
121948b867SPrzemek Kitszel  * ice_vc_get_max_frame_size - get max frame size allowed for VF
131948b867SPrzemek Kitszel  * @vf: VF used to determine max frame size
141948b867SPrzemek Kitszel  *
151948b867SPrzemek Kitszel  * Max frame size is determined based on the current port's max frame size and
161948b867SPrzemek Kitszel  * whether a port VLAN is configured on this VF. The VF is not aware whether
171948b867SPrzemek Kitszel  * it's in a port VLAN so the PF needs to account for this in max frame size
181948b867SPrzemek Kitszel  * checks and sending the max frame size to the VF.
191948b867SPrzemek Kitszel  */
20c762b0a5SPrzemek Kitszel u16 ice_vc_get_max_frame_size(struct ice_vf *vf)
211948b867SPrzemek Kitszel {
221948b867SPrzemek Kitszel 	struct ice_port_info *pi = ice_vf_get_port_info(vf);
231948b867SPrzemek Kitszel 	u16 max_frame_size;
241948b867SPrzemek Kitszel 
251948b867SPrzemek Kitszel 	max_frame_size = pi->phy.link_info.max_frame_size;
261948b867SPrzemek Kitszel 
271948b867SPrzemek Kitszel 	if (ice_vf_is_port_vlan_ena(vf))
281948b867SPrzemek Kitszel 		max_frame_size -= VLAN_HLEN;
291948b867SPrzemek Kitszel 
301948b867SPrzemek Kitszel 	return max_frame_size;
311948b867SPrzemek Kitszel }
321948b867SPrzemek Kitszel 
331948b867SPrzemek Kitszel /**
341948b867SPrzemek Kitszel  * ice_vc_isvalid_q_id
351948b867SPrzemek Kitszel  * @vsi: VSI to check queue ID against
361948b867SPrzemek Kitszel  * @qid: VSI relative queue ID
371948b867SPrzemek Kitszel  *
381948b867SPrzemek Kitszel  * check for the valid queue ID
391948b867SPrzemek Kitszel  */
401948b867SPrzemek Kitszel static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u16 qid)
411948b867SPrzemek Kitszel {
421948b867SPrzemek Kitszel 	/* allocated Tx and Rx queues should be always equal for VF VSI */
431948b867SPrzemek Kitszel 	return qid < vsi->alloc_txq;
441948b867SPrzemek Kitszel }
451948b867SPrzemek Kitszel 
461948b867SPrzemek Kitszel /**
471948b867SPrzemek Kitszel  * ice_vc_isvalid_ring_len
481948b867SPrzemek Kitszel  * @ring_len: length of ring
491948b867SPrzemek Kitszel  *
501948b867SPrzemek Kitszel  * check for the valid ring count, should be multiple of ICE_REQ_DESC_MULTIPLE
511948b867SPrzemek Kitszel  * or zero
521948b867SPrzemek Kitszel  */
531948b867SPrzemek Kitszel static bool ice_vc_isvalid_ring_len(u16 ring_len)
541948b867SPrzemek Kitszel {
551948b867SPrzemek Kitszel 	return ring_len == 0 ||
561948b867SPrzemek Kitszel 	       (ring_len >= ICE_MIN_NUM_DESC &&
57*ccde82e9SPaul Greenwalt 		ring_len <= ICE_MAX_NUM_DESC_E810 &&
581948b867SPrzemek Kitszel 		!(ring_len % ICE_REQ_DESC_MULTIPLE));
591948b867SPrzemek Kitszel }
601948b867SPrzemek Kitszel 
611948b867SPrzemek Kitszel /**
621948b867SPrzemek Kitszel  * ice_vf_cfg_qs_bw - Configure per queue bandwidth
631948b867SPrzemek Kitszel  * @vf: pointer to the VF info
641948b867SPrzemek Kitszel  * @num_queues: number of queues to be configured
651948b867SPrzemek Kitszel  *
661948b867SPrzemek Kitszel  * Configure per queue bandwidth.
671948b867SPrzemek Kitszel  *
681948b867SPrzemek Kitszel  * Return: 0 on success or negative error value.
691948b867SPrzemek Kitszel  */
701948b867SPrzemek Kitszel static int ice_vf_cfg_qs_bw(struct ice_vf *vf, u16 num_queues)
711948b867SPrzemek Kitszel {
721948b867SPrzemek Kitszel 	struct ice_hw *hw = &vf->pf->hw;
731948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
741948b867SPrzemek Kitszel 	int ret;
751948b867SPrzemek Kitszel 	u16 i;
761948b867SPrzemek Kitszel 
771948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
781948b867SPrzemek Kitszel 	if (!vsi)
791948b867SPrzemek Kitszel 		return -EINVAL;
801948b867SPrzemek Kitszel 
811948b867SPrzemek Kitszel 	for (i = 0; i < num_queues; i++) {
821948b867SPrzemek Kitszel 		u32 p_rate, min_rate;
831948b867SPrzemek Kitszel 		u8 tc;
841948b867SPrzemek Kitszel 
851948b867SPrzemek Kitszel 		p_rate = vf->qs_bw[i].peak;
861948b867SPrzemek Kitszel 		min_rate = vf->qs_bw[i].committed;
871948b867SPrzemek Kitszel 		tc = vf->qs_bw[i].tc;
881948b867SPrzemek Kitszel 		if (p_rate)
891948b867SPrzemek Kitszel 			ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc,
901948b867SPrzemek Kitszel 					       vf->qs_bw[i].queue_id,
911948b867SPrzemek Kitszel 					       ICE_MAX_BW, p_rate);
921948b867SPrzemek Kitszel 		else
931948b867SPrzemek Kitszel 			ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc,
941948b867SPrzemek Kitszel 						    vf->qs_bw[i].queue_id,
951948b867SPrzemek Kitszel 						    ICE_MAX_BW);
961948b867SPrzemek Kitszel 		if (ret)
971948b867SPrzemek Kitszel 			return ret;
981948b867SPrzemek Kitszel 
991948b867SPrzemek Kitszel 		if (min_rate)
1001948b867SPrzemek Kitszel 			ret = ice_cfg_q_bw_lmt(hw->port_info, vsi->idx, tc,
1011948b867SPrzemek Kitszel 					       vf->qs_bw[i].queue_id,
1021948b867SPrzemek Kitszel 					       ICE_MIN_BW, min_rate);
1031948b867SPrzemek Kitszel 		else
1041948b867SPrzemek Kitszel 			ret = ice_cfg_q_bw_dflt_lmt(hw->port_info, vsi->idx, tc,
1051948b867SPrzemek Kitszel 						    vf->qs_bw[i].queue_id,
1061948b867SPrzemek Kitszel 						    ICE_MIN_BW);
1071948b867SPrzemek Kitszel 
1081948b867SPrzemek Kitszel 		if (ret)
1091948b867SPrzemek Kitszel 			return ret;
1101948b867SPrzemek Kitszel 	}
1111948b867SPrzemek Kitszel 
1121948b867SPrzemek Kitszel 	return 0;
1131948b867SPrzemek Kitszel }
1141948b867SPrzemek Kitszel 
1151948b867SPrzemek Kitszel /**
1161948b867SPrzemek Kitszel  * ice_vf_cfg_q_quanta_profile - Configure quanta profile
1171948b867SPrzemek Kitszel  * @vf: pointer to the VF info
1181948b867SPrzemek Kitszel  * @quanta_prof_idx: pointer to the quanta profile index
1191948b867SPrzemek Kitszel  * @quanta_size: quanta size to be set
1201948b867SPrzemek Kitszel  *
1211948b867SPrzemek Kitszel  * This function chooses available quanta profile and configures the register.
1221948b867SPrzemek Kitszel  * The quanta profile is evenly divided by the number of device ports, and then
1231948b867SPrzemek Kitszel  * available to the specific PF and VFs. The first profile for each PF is a
1241948b867SPrzemek Kitszel  * reserved default profile. Only quanta size of the rest unused profile can be
1251948b867SPrzemek Kitszel  * modified.
1261948b867SPrzemek Kitszel  *
1271948b867SPrzemek Kitszel  * Return: 0 on success or negative error value.
1281948b867SPrzemek Kitszel  */
1291948b867SPrzemek Kitszel static int ice_vf_cfg_q_quanta_profile(struct ice_vf *vf, u16 quanta_size,
1301948b867SPrzemek Kitszel 				       u16 *quanta_prof_idx)
1311948b867SPrzemek Kitszel {
1321948b867SPrzemek Kitszel 	const u16 n_desc = calc_quanta_desc(quanta_size);
1331948b867SPrzemek Kitszel 	struct ice_hw *hw = &vf->pf->hw;
1341948b867SPrzemek Kitszel 	const u16 n_cmd = 2 * n_desc;
1351948b867SPrzemek Kitszel 	struct ice_pf *pf = vf->pf;
1361948b867SPrzemek Kitszel 	u16 per_pf, begin_id;
1371948b867SPrzemek Kitszel 	u8 n_used;
1381948b867SPrzemek Kitszel 	u32 reg;
1391948b867SPrzemek Kitszel 
1401948b867SPrzemek Kitszel 	begin_id = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) / hw->dev_caps.num_funcs *
1411948b867SPrzemek Kitszel 		   hw->logical_pf_id;
1421948b867SPrzemek Kitszel 
1431948b867SPrzemek Kitszel 	if (quanta_size == ICE_DFLT_QUANTA) {
1441948b867SPrzemek Kitszel 		*quanta_prof_idx = begin_id;
1451948b867SPrzemek Kitszel 	} else {
1461948b867SPrzemek Kitszel 		per_pf = (GLCOMM_QUANTA_PROF_MAX_INDEX + 1) /
1471948b867SPrzemek Kitszel 			 hw->dev_caps.num_funcs;
1481948b867SPrzemek Kitszel 		n_used = pf->num_quanta_prof_used;
1491948b867SPrzemek Kitszel 		if (n_used < per_pf) {
1501948b867SPrzemek Kitszel 			*quanta_prof_idx = begin_id + 1 + n_used;
1511948b867SPrzemek Kitszel 			pf->num_quanta_prof_used++;
1521948b867SPrzemek Kitszel 		} else {
1531948b867SPrzemek Kitszel 			return -EINVAL;
1541948b867SPrzemek Kitszel 		}
1551948b867SPrzemek Kitszel 	}
1561948b867SPrzemek Kitszel 
1571948b867SPrzemek Kitszel 	reg = FIELD_PREP(GLCOMM_QUANTA_PROF_QUANTA_SIZE_M, quanta_size) |
1581948b867SPrzemek Kitszel 	      FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_CMD_M, n_cmd) |
1591948b867SPrzemek Kitszel 	      FIELD_PREP(GLCOMM_QUANTA_PROF_MAX_DESC_M, n_desc);
1601948b867SPrzemek Kitszel 	wr32(hw, GLCOMM_QUANTA_PROF(*quanta_prof_idx), reg);
1611948b867SPrzemek Kitszel 
1621948b867SPrzemek Kitszel 	return 0;
1631948b867SPrzemek Kitszel }
1641948b867SPrzemek Kitszel 
1651948b867SPrzemek Kitszel /**
1661948b867SPrzemek Kitszel  * ice_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTCHNL
1671948b867SPrzemek Kitszel  * @vqs: virtchnl_queue_select structure containing bitmaps to validate
1681948b867SPrzemek Kitszel  *
1691948b867SPrzemek Kitszel  * Return true on successful validation, else false
1701948b867SPrzemek Kitszel  */
1711948b867SPrzemek Kitszel static bool ice_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs)
1721948b867SPrzemek Kitszel {
1731948b867SPrzemek Kitszel 	if ((!vqs->rx_queues && !vqs->tx_queues) ||
1741948b867SPrzemek Kitszel 	    vqs->rx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF) ||
1751948b867SPrzemek Kitszel 	    vqs->tx_queues >= BIT(ICE_MAX_RSS_QS_PER_VF))
1761948b867SPrzemek Kitszel 		return false;
1771948b867SPrzemek Kitszel 
1781948b867SPrzemek Kitszel 	return true;
1791948b867SPrzemek Kitszel }
1801948b867SPrzemek Kitszel 
1811948b867SPrzemek Kitszel /**
1821948b867SPrzemek Kitszel  * ice_vf_ena_txq_interrupt - enable Tx queue interrupt via QINT_TQCTL
1831948b867SPrzemek Kitszel  * @vsi: VSI of the VF to configure
1841948b867SPrzemek Kitszel  * @q_idx: VF queue index used to determine the queue in the PF's space
1851948b867SPrzemek Kitszel  */
1861948b867SPrzemek Kitszel void ice_vf_ena_txq_interrupt(struct ice_vsi *vsi, u32 q_idx)
1871948b867SPrzemek Kitszel {
1881948b867SPrzemek Kitszel 	struct ice_hw *hw = &vsi->back->hw;
1891948b867SPrzemek Kitszel 	u32 pfq = vsi->txq_map[q_idx];
1901948b867SPrzemek Kitszel 	u32 reg;
1911948b867SPrzemek Kitszel 
1921948b867SPrzemek Kitszel 	reg = rd32(hw, QINT_TQCTL(pfq));
1931948b867SPrzemek Kitszel 
1941948b867SPrzemek Kitszel 	/* MSI-X index 0 in the VF's space is always for the OICR, which means
1951948b867SPrzemek Kitszel 	 * this is most likely a poll mode VF driver, so don't enable an
1961948b867SPrzemek Kitszel 	 * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP
1971948b867SPrzemek Kitszel 	 */
1981948b867SPrzemek Kitszel 	if (!(reg & QINT_TQCTL_MSIX_INDX_M))
1991948b867SPrzemek Kitszel 		return;
2001948b867SPrzemek Kitszel 
2011948b867SPrzemek Kitszel 	wr32(hw, QINT_TQCTL(pfq), reg | QINT_TQCTL_CAUSE_ENA_M);
2021948b867SPrzemek Kitszel }
2031948b867SPrzemek Kitszel 
2041948b867SPrzemek Kitszel /**
2051948b867SPrzemek Kitszel  * ice_vf_ena_rxq_interrupt - enable Tx queue interrupt via QINT_RQCTL
2061948b867SPrzemek Kitszel  * @vsi: VSI of the VF to configure
2071948b867SPrzemek Kitszel  * @q_idx: VF queue index used to determine the queue in the PF's space
2081948b867SPrzemek Kitszel  */
2091948b867SPrzemek Kitszel void ice_vf_ena_rxq_interrupt(struct ice_vsi *vsi, u32 q_idx)
2101948b867SPrzemek Kitszel {
2111948b867SPrzemek Kitszel 	struct ice_hw *hw = &vsi->back->hw;
2121948b867SPrzemek Kitszel 	u32 pfq = vsi->rxq_map[q_idx];
2131948b867SPrzemek Kitszel 	u32 reg;
2141948b867SPrzemek Kitszel 
2151948b867SPrzemek Kitszel 	reg = rd32(hw, QINT_RQCTL(pfq));
2161948b867SPrzemek Kitszel 
2171948b867SPrzemek Kitszel 	/* MSI-X index 0 in the VF's space is always for the OICR, which means
2181948b867SPrzemek Kitszel 	 * this is most likely a poll mode VF driver, so don't enable an
2191948b867SPrzemek Kitszel 	 * interrupt that was never configured via VIRTCHNL_OP_CONFIG_IRQ_MAP
2201948b867SPrzemek Kitszel 	 */
2211948b867SPrzemek Kitszel 	if (!(reg & QINT_RQCTL_MSIX_INDX_M))
2221948b867SPrzemek Kitszel 		return;
2231948b867SPrzemek Kitszel 
2241948b867SPrzemek Kitszel 	wr32(hw, QINT_RQCTL(pfq), reg | QINT_RQCTL_CAUSE_ENA_M);
2251948b867SPrzemek Kitszel }
2261948b867SPrzemek Kitszel 
2271948b867SPrzemek Kitszel /**
2281948b867SPrzemek Kitszel  * ice_vc_ena_qs_msg
2291948b867SPrzemek Kitszel  * @vf: pointer to the VF info
2301948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer
2311948b867SPrzemek Kitszel  *
2321948b867SPrzemek Kitszel  * called from the VF to enable all or specific queue(s)
2331948b867SPrzemek Kitszel  */
234c762b0a5SPrzemek Kitszel int ice_vc_ena_qs_msg(struct ice_vf *vf, u8 *msg)
2351948b867SPrzemek Kitszel {
2361948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
2371948b867SPrzemek Kitszel 	struct virtchnl_queue_select *vqs =
2381948b867SPrzemek Kitszel 	    (struct virtchnl_queue_select *)msg;
2391948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
2401948b867SPrzemek Kitszel 	unsigned long q_map;
2411948b867SPrzemek Kitszel 	u16 vf_q_id;
2421948b867SPrzemek Kitszel 
2431948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
2441948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2451948b867SPrzemek Kitszel 		goto error_param;
2461948b867SPrzemek Kitszel 	}
2471948b867SPrzemek Kitszel 
2481948b867SPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) {
2491948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2501948b867SPrzemek Kitszel 		goto error_param;
2511948b867SPrzemek Kitszel 	}
2521948b867SPrzemek Kitszel 
2531948b867SPrzemek Kitszel 	if (!ice_vc_validate_vqs_bitmaps(vqs)) {
2541948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2551948b867SPrzemek Kitszel 		goto error_param;
2561948b867SPrzemek Kitszel 	}
2571948b867SPrzemek Kitszel 
2581948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
2591948b867SPrzemek Kitszel 	if (!vsi) {
2601948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2611948b867SPrzemek Kitszel 		goto error_param;
2621948b867SPrzemek Kitszel 	}
2631948b867SPrzemek Kitszel 
2641948b867SPrzemek Kitszel 	/* Enable only Rx rings, Tx rings were enabled by the FW when the
2651948b867SPrzemek Kitszel 	 * Tx queue group list was configured and the context bits were
2661948b867SPrzemek Kitszel 	 * programmed using ice_vsi_cfg_txqs
2671948b867SPrzemek Kitszel 	 */
2681948b867SPrzemek Kitszel 	q_map = vqs->rx_queues;
2691948b867SPrzemek Kitszel 	for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
2701948b867SPrzemek Kitszel 		if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
2711948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2721948b867SPrzemek Kitszel 			goto error_param;
2731948b867SPrzemek Kitszel 		}
2741948b867SPrzemek Kitszel 
2751948b867SPrzemek Kitszel 		/* Skip queue if enabled */
2761948b867SPrzemek Kitszel 		if (test_bit(vf_q_id, vf->rxq_ena))
2771948b867SPrzemek Kitszel 			continue;
2781948b867SPrzemek Kitszel 
2791948b867SPrzemek Kitszel 		if (ice_vsi_ctrl_one_rx_ring(vsi, true, vf_q_id, true)) {
2801948b867SPrzemek Kitszel 			dev_err(ice_pf_to_dev(vsi->back), "Failed to enable Rx ring %d on VSI %d\n",
2811948b867SPrzemek Kitszel 				vf_q_id, vsi->vsi_num);
2821948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2831948b867SPrzemek Kitszel 			goto error_param;
2841948b867SPrzemek Kitszel 		}
2851948b867SPrzemek Kitszel 
2861948b867SPrzemek Kitszel 		ice_vf_ena_rxq_interrupt(vsi, vf_q_id);
2871948b867SPrzemek Kitszel 		set_bit(vf_q_id, vf->rxq_ena);
2881948b867SPrzemek Kitszel 	}
2891948b867SPrzemek Kitszel 
2901948b867SPrzemek Kitszel 	q_map = vqs->tx_queues;
2911948b867SPrzemek Kitszel 	for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
2921948b867SPrzemek Kitszel 		if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
2931948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
2941948b867SPrzemek Kitszel 			goto error_param;
2951948b867SPrzemek Kitszel 		}
2961948b867SPrzemek Kitszel 
2971948b867SPrzemek Kitszel 		/* Skip queue if enabled */
2981948b867SPrzemek Kitszel 		if (test_bit(vf_q_id, vf->txq_ena))
2991948b867SPrzemek Kitszel 			continue;
3001948b867SPrzemek Kitszel 
3011948b867SPrzemek Kitszel 		ice_vf_ena_txq_interrupt(vsi, vf_q_id);
3021948b867SPrzemek Kitszel 		set_bit(vf_q_id, vf->txq_ena);
3031948b867SPrzemek Kitszel 	}
3041948b867SPrzemek Kitszel 
3051948b867SPrzemek Kitszel 	/* Set flag to indicate that queues are enabled */
3061948b867SPrzemek Kitszel 	if (v_ret == VIRTCHNL_STATUS_SUCCESS)
3071948b867SPrzemek Kitszel 		set_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
3081948b867SPrzemek Kitszel 
3091948b867SPrzemek Kitszel error_param:
3101948b867SPrzemek Kitszel 	/* send the response to the VF */
3111948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, v_ret,
3121948b867SPrzemek Kitszel 				     NULL, 0);
3131948b867SPrzemek Kitszel }
3141948b867SPrzemek Kitszel 
3151948b867SPrzemek Kitszel /**
3161948b867SPrzemek Kitszel  * ice_vf_vsi_dis_single_txq - disable a single Tx queue
3171948b867SPrzemek Kitszel  * @vf: VF to disable queue for
3181948b867SPrzemek Kitszel  * @vsi: VSI for the VF
3191948b867SPrzemek Kitszel  * @q_id: VF relative (0-based) queue ID
3201948b867SPrzemek Kitszel  *
3211948b867SPrzemek Kitszel  * Attempt to disable the Tx queue passed in. If the Tx queue was successfully
3221948b867SPrzemek Kitszel  * disabled then clear q_id bit in the enabled queues bitmap and return
3231948b867SPrzemek Kitszel  * success. Otherwise return error.
3241948b867SPrzemek Kitszel  */
3251948b867SPrzemek Kitszel int ice_vf_vsi_dis_single_txq(struct ice_vf *vf, struct ice_vsi *vsi, u16 q_id)
3261948b867SPrzemek Kitszel {
3271948b867SPrzemek Kitszel 	struct ice_txq_meta txq_meta = { 0 };
3281948b867SPrzemek Kitszel 	struct ice_tx_ring *ring;
3291948b867SPrzemek Kitszel 	int err;
3301948b867SPrzemek Kitszel 
3311948b867SPrzemek Kitszel 	if (!test_bit(q_id, vf->txq_ena))
3321948b867SPrzemek Kitszel 		dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n",
3331948b867SPrzemek Kitszel 			q_id, vsi->vsi_num);
3341948b867SPrzemek Kitszel 
3351948b867SPrzemek Kitszel 	ring = vsi->tx_rings[q_id];
3361948b867SPrzemek Kitszel 	if (!ring)
3371948b867SPrzemek Kitszel 		return -EINVAL;
3381948b867SPrzemek Kitszel 
3391948b867SPrzemek Kitszel 	ice_fill_txq_meta(vsi, ring, &txq_meta);
3401948b867SPrzemek Kitszel 
3411948b867SPrzemek Kitszel 	err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, ring, &txq_meta);
3421948b867SPrzemek Kitszel 	if (err) {
3431948b867SPrzemek Kitszel 		dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n",
3441948b867SPrzemek Kitszel 			q_id, vsi->vsi_num);
3451948b867SPrzemek Kitszel 		return err;
3461948b867SPrzemek Kitszel 	}
3471948b867SPrzemek Kitszel 
3481948b867SPrzemek Kitszel 	/* Clear enabled queues flag */
3491948b867SPrzemek Kitszel 	clear_bit(q_id, vf->txq_ena);
3501948b867SPrzemek Kitszel 
3511948b867SPrzemek Kitszel 	return 0;
3521948b867SPrzemek Kitszel }
3531948b867SPrzemek Kitszel 
3541948b867SPrzemek Kitszel /**
3551948b867SPrzemek Kitszel  * ice_vc_dis_qs_msg
3561948b867SPrzemek Kitszel  * @vf: pointer to the VF info
3571948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer
3581948b867SPrzemek Kitszel  *
3591948b867SPrzemek Kitszel  * called from the VF to disable all or specific queue(s)
3601948b867SPrzemek Kitszel  */
361c762b0a5SPrzemek Kitszel int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg)
3621948b867SPrzemek Kitszel {
3631948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
3641948b867SPrzemek Kitszel 	struct virtchnl_queue_select *vqs =
3651948b867SPrzemek Kitszel 	    (struct virtchnl_queue_select *)msg;
3661948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
3671948b867SPrzemek Kitszel 	unsigned long q_map;
3681948b867SPrzemek Kitszel 	u16 vf_q_id;
3691948b867SPrzemek Kitszel 
3701948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) &&
3711948b867SPrzemek Kitszel 	    !test_bit(ICE_VF_STATE_QS_ENA, vf->vf_states)) {
3721948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
3731948b867SPrzemek Kitszel 		goto error_param;
3741948b867SPrzemek Kitszel 	}
3751948b867SPrzemek Kitszel 
3761948b867SPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, vqs->vsi_id)) {
3771948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
3781948b867SPrzemek Kitszel 		goto error_param;
3791948b867SPrzemek Kitszel 	}
3801948b867SPrzemek Kitszel 
3811948b867SPrzemek Kitszel 	if (!ice_vc_validate_vqs_bitmaps(vqs)) {
3821948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
3831948b867SPrzemek Kitszel 		goto error_param;
3841948b867SPrzemek Kitszel 	}
3851948b867SPrzemek Kitszel 
3861948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
3871948b867SPrzemek Kitszel 	if (!vsi) {
3881948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
3891948b867SPrzemek Kitszel 		goto error_param;
3901948b867SPrzemek Kitszel 	}
3911948b867SPrzemek Kitszel 
3921948b867SPrzemek Kitszel 	if (vqs->tx_queues) {
3931948b867SPrzemek Kitszel 		q_map = vqs->tx_queues;
3941948b867SPrzemek Kitszel 
3951948b867SPrzemek Kitszel 		for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
3961948b867SPrzemek Kitszel 			if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
3971948b867SPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
3981948b867SPrzemek Kitszel 				goto error_param;
3991948b867SPrzemek Kitszel 			}
4001948b867SPrzemek Kitszel 
4011948b867SPrzemek Kitszel 			if (ice_vf_vsi_dis_single_txq(vf, vsi, vf_q_id)) {
4021948b867SPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4031948b867SPrzemek Kitszel 				goto error_param;
4041948b867SPrzemek Kitszel 			}
4051948b867SPrzemek Kitszel 		}
4061948b867SPrzemek Kitszel 	}
4071948b867SPrzemek Kitszel 
4081948b867SPrzemek Kitszel 	q_map = vqs->rx_queues;
4091948b867SPrzemek Kitszel 	/* speed up Rx queue disable by batching them if possible */
4101948b867SPrzemek Kitszel 	if (q_map &&
4111948b867SPrzemek Kitszel 	    bitmap_equal(&q_map, vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF)) {
4121948b867SPrzemek Kitszel 		if (ice_vsi_stop_all_rx_rings(vsi)) {
4131948b867SPrzemek Kitszel 			dev_err(ice_pf_to_dev(vsi->back), "Failed to stop all Rx rings on VSI %d\n",
4141948b867SPrzemek Kitszel 				vsi->vsi_num);
4151948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4161948b867SPrzemek Kitszel 			goto error_param;
4171948b867SPrzemek Kitszel 		}
4181948b867SPrzemek Kitszel 
4191948b867SPrzemek Kitszel 		bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF);
4201948b867SPrzemek Kitszel 	} else if (q_map) {
4211948b867SPrzemek Kitszel 		for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
4221948b867SPrzemek Kitszel 			if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
4231948b867SPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4241948b867SPrzemek Kitszel 				goto error_param;
4251948b867SPrzemek Kitszel 			}
4261948b867SPrzemek Kitszel 
4271948b867SPrzemek Kitszel 			/* Skip queue if not enabled */
4281948b867SPrzemek Kitszel 			if (!test_bit(vf_q_id, vf->rxq_ena))
4291948b867SPrzemek Kitszel 				continue;
4301948b867SPrzemek Kitszel 
4311948b867SPrzemek Kitszel 			if (ice_vsi_ctrl_one_rx_ring(vsi, false, vf_q_id,
4321948b867SPrzemek Kitszel 						     true)) {
4331948b867SPrzemek Kitszel 				dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Rx ring %d on VSI %d\n",
4341948b867SPrzemek Kitszel 					vf_q_id, vsi->vsi_num);
4351948b867SPrzemek Kitszel 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4361948b867SPrzemek Kitszel 				goto error_param;
4371948b867SPrzemek Kitszel 			}
4381948b867SPrzemek Kitszel 
4391948b867SPrzemek Kitszel 			/* Clear enabled queues flag */
4401948b867SPrzemek Kitszel 			clear_bit(vf_q_id, vf->rxq_ena);
4411948b867SPrzemek Kitszel 		}
4421948b867SPrzemek Kitszel 	}
4431948b867SPrzemek Kitszel 
4441948b867SPrzemek Kitszel 	/* Clear enabled queues flag */
4451948b867SPrzemek Kitszel 	if (v_ret == VIRTCHNL_STATUS_SUCCESS && ice_vf_has_no_qs_ena(vf))
4461948b867SPrzemek Kitszel 		clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states);
4471948b867SPrzemek Kitszel 
4481948b867SPrzemek Kitszel error_param:
4491948b867SPrzemek Kitszel 	/* send the response to the VF */
4501948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DISABLE_QUEUES, v_ret,
4511948b867SPrzemek Kitszel 				     NULL, 0);
4521948b867SPrzemek Kitszel }
4531948b867SPrzemek Kitszel 
4541948b867SPrzemek Kitszel /**
4551948b867SPrzemek Kitszel  * ice_cfg_interrupt
4561948b867SPrzemek Kitszel  * @vf: pointer to the VF info
4571948b867SPrzemek Kitszel  * @vsi: the VSI being configured
4581948b867SPrzemek Kitszel  * @map: vector map for mapping vectors to queues
4591948b867SPrzemek Kitszel  * @q_vector: structure for interrupt vector
4601948b867SPrzemek Kitszel  * configure the IRQ to queue map
4611948b867SPrzemek Kitszel  */
4621948b867SPrzemek Kitszel static enum virtchnl_status_code
4631948b867SPrzemek Kitszel ice_cfg_interrupt(struct ice_vf *vf, struct ice_vsi *vsi,
4641948b867SPrzemek Kitszel 		  struct virtchnl_vector_map *map,
4651948b867SPrzemek Kitszel 		  struct ice_q_vector *q_vector)
4661948b867SPrzemek Kitszel {
4671948b867SPrzemek Kitszel 	u16 vsi_q_id, vsi_q_id_idx;
4681948b867SPrzemek Kitszel 	unsigned long qmap;
4691948b867SPrzemek Kitszel 
4701948b867SPrzemek Kitszel 	q_vector->num_ring_rx = 0;
4711948b867SPrzemek Kitszel 	q_vector->num_ring_tx = 0;
4721948b867SPrzemek Kitszel 
4731948b867SPrzemek Kitszel 	qmap = map->rxq_map;
4741948b867SPrzemek Kitszel 	for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) {
4751948b867SPrzemek Kitszel 		vsi_q_id = vsi_q_id_idx;
4761948b867SPrzemek Kitszel 
4771948b867SPrzemek Kitszel 		if (!ice_vc_isvalid_q_id(vsi, vsi_q_id))
4781948b867SPrzemek Kitszel 			return VIRTCHNL_STATUS_ERR_PARAM;
4791948b867SPrzemek Kitszel 
4801948b867SPrzemek Kitszel 		q_vector->num_ring_rx++;
4811948b867SPrzemek Kitszel 		q_vector->rx.itr_idx = map->rxitr_idx;
4821948b867SPrzemek Kitszel 		vsi->rx_rings[vsi_q_id]->q_vector = q_vector;
4831948b867SPrzemek Kitszel 		ice_cfg_rxq_interrupt(vsi, vsi_q_id,
4841948b867SPrzemek Kitszel 				      q_vector->vf_reg_idx,
4851948b867SPrzemek Kitszel 				      q_vector->rx.itr_idx);
4861948b867SPrzemek Kitszel 	}
4871948b867SPrzemek Kitszel 
4881948b867SPrzemek Kitszel 	qmap = map->txq_map;
4891948b867SPrzemek Kitszel 	for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) {
4901948b867SPrzemek Kitszel 		vsi_q_id = vsi_q_id_idx;
4911948b867SPrzemek Kitszel 
4921948b867SPrzemek Kitszel 		if (!ice_vc_isvalid_q_id(vsi, vsi_q_id))
4931948b867SPrzemek Kitszel 			return VIRTCHNL_STATUS_ERR_PARAM;
4941948b867SPrzemek Kitszel 
4951948b867SPrzemek Kitszel 		q_vector->num_ring_tx++;
4961948b867SPrzemek Kitszel 		q_vector->tx.itr_idx = map->txitr_idx;
4971948b867SPrzemek Kitszel 		vsi->tx_rings[vsi_q_id]->q_vector = q_vector;
4981948b867SPrzemek Kitszel 		ice_cfg_txq_interrupt(vsi, vsi_q_id,
4991948b867SPrzemek Kitszel 				      q_vector->vf_reg_idx,
5001948b867SPrzemek Kitszel 				      q_vector->tx.itr_idx);
5011948b867SPrzemek Kitszel 	}
5021948b867SPrzemek Kitszel 
5031948b867SPrzemek Kitszel 	return VIRTCHNL_STATUS_SUCCESS;
5041948b867SPrzemek Kitszel }
5051948b867SPrzemek Kitszel 
5061948b867SPrzemek Kitszel /**
5071948b867SPrzemek Kitszel  * ice_vc_cfg_irq_map_msg
5081948b867SPrzemek Kitszel  * @vf: pointer to the VF info
5091948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer
5101948b867SPrzemek Kitszel  *
5111948b867SPrzemek Kitszel  * called from the VF to configure the IRQ to queue map
5121948b867SPrzemek Kitszel  */
513c762b0a5SPrzemek Kitszel int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg)
5141948b867SPrzemek Kitszel {
5151948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
5161948b867SPrzemek Kitszel 	u16 num_q_vectors_mapped, vsi_id, vector_id;
5171948b867SPrzemek Kitszel 	struct virtchnl_irq_map_info *irqmap_info;
5181948b867SPrzemek Kitszel 	struct virtchnl_vector_map *map;
5191948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
5201948b867SPrzemek Kitszel 	int i;
5211948b867SPrzemek Kitszel 
5221948b867SPrzemek Kitszel 	irqmap_info = (struct virtchnl_irq_map_info *)msg;
5231948b867SPrzemek Kitszel 	num_q_vectors_mapped = irqmap_info->num_vectors;
5241948b867SPrzemek Kitszel 
5251948b867SPrzemek Kitszel 	/* Check to make sure number of VF vectors mapped is not greater than
5261948b867SPrzemek Kitszel 	 * number of VF vectors originally allocated, and check that
5271948b867SPrzemek Kitszel 	 * there is actually at least a single VF queue vector mapped
5281948b867SPrzemek Kitszel 	 */
5291948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) ||
5301948b867SPrzemek Kitszel 	    vf->num_msix < num_q_vectors_mapped ||
5311948b867SPrzemek Kitszel 	    !num_q_vectors_mapped) {
5321948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
5331948b867SPrzemek Kitszel 		goto error_param;
5341948b867SPrzemek Kitszel 	}
5351948b867SPrzemek Kitszel 
5361948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
5371948b867SPrzemek Kitszel 	if (!vsi) {
5381948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
5391948b867SPrzemek Kitszel 		goto error_param;
5401948b867SPrzemek Kitszel 	}
5411948b867SPrzemek Kitszel 
5421948b867SPrzemek Kitszel 	for (i = 0; i < num_q_vectors_mapped; i++) {
5431948b867SPrzemek Kitszel 		struct ice_q_vector *q_vector;
5441948b867SPrzemek Kitszel 
5451948b867SPrzemek Kitszel 		map = &irqmap_info->vecmap[i];
5461948b867SPrzemek Kitszel 
5471948b867SPrzemek Kitszel 		vector_id = map->vector_id;
5481948b867SPrzemek Kitszel 		vsi_id = map->vsi_id;
5491948b867SPrzemek Kitszel 		/* vector_id is always 0-based for each VF, and can never be
5501948b867SPrzemek Kitszel 		 * larger than or equal to the max allowed interrupts per VF
5511948b867SPrzemek Kitszel 		 */
5521948b867SPrzemek Kitszel 		if (!(vector_id < vf->num_msix) ||
5531948b867SPrzemek Kitszel 		    !ice_vc_isvalid_vsi_id(vf, vsi_id) ||
5541948b867SPrzemek Kitszel 		    (!vector_id && (map->rxq_map || map->txq_map))) {
5551948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
5561948b867SPrzemek Kitszel 			goto error_param;
5571948b867SPrzemek Kitszel 		}
5581948b867SPrzemek Kitszel 
5591948b867SPrzemek Kitszel 		/* No need to map VF miscellaneous or rogue vector */
5601948b867SPrzemek Kitszel 		if (!vector_id)
5611948b867SPrzemek Kitszel 			continue;
5621948b867SPrzemek Kitszel 
5631948b867SPrzemek Kitszel 		/* Subtract non queue vector from vector_id passed by VF
5641948b867SPrzemek Kitszel 		 * to get actual number of VSI queue vector array index
5651948b867SPrzemek Kitszel 		 */
5661948b867SPrzemek Kitszel 		q_vector = vsi->q_vectors[vector_id - ICE_NONQ_VECS_VF];
5671948b867SPrzemek Kitszel 		if (!q_vector) {
5681948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
5691948b867SPrzemek Kitszel 			goto error_param;
5701948b867SPrzemek Kitszel 		}
5711948b867SPrzemek Kitszel 
5721948b867SPrzemek Kitszel 		/* lookout for the invalid queue index */
5731948b867SPrzemek Kitszel 		v_ret = ice_cfg_interrupt(vf, vsi, map, q_vector);
5741948b867SPrzemek Kitszel 		if (v_ret)
5751948b867SPrzemek Kitszel 			goto error_param;
5761948b867SPrzemek Kitszel 	}
5771948b867SPrzemek Kitszel 
5781948b867SPrzemek Kitszel error_param:
5791948b867SPrzemek Kitszel 	/* send the response to the VF */
5801948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_IRQ_MAP, v_ret,
5811948b867SPrzemek Kitszel 				     NULL, 0);
5821948b867SPrzemek Kitszel }
5831948b867SPrzemek Kitszel 
5841948b867SPrzemek Kitszel /**
5851948b867SPrzemek Kitszel  * ice_vc_cfg_q_bw - Configure per queue bandwidth
5861948b867SPrzemek Kitszel  * @vf: pointer to the VF info
5871948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer which holds the command descriptor
5881948b867SPrzemek Kitszel  *
5891948b867SPrzemek Kitszel  * Configure VF queues bandwidth.
5901948b867SPrzemek Kitszel  *
5911948b867SPrzemek Kitszel  * Return: 0 on success or negative error value.
5921948b867SPrzemek Kitszel  */
593c762b0a5SPrzemek Kitszel int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg)
5941948b867SPrzemek Kitszel {
5951948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
5961948b867SPrzemek Kitszel 	struct virtchnl_queues_bw_cfg *qbw =
5971948b867SPrzemek Kitszel 		(struct virtchnl_queues_bw_cfg *)msg;
5981948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
5991948b867SPrzemek Kitszel 	u16 i;
6001948b867SPrzemek Kitszel 
6011948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) ||
6021948b867SPrzemek Kitszel 	    !ice_vc_isvalid_vsi_id(vf, qbw->vsi_id)) {
6031948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6041948b867SPrzemek Kitszel 		goto err;
6051948b867SPrzemek Kitszel 	}
6061948b867SPrzemek Kitszel 
6071948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
6081948b867SPrzemek Kitszel 	if (!vsi) {
6091948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6101948b867SPrzemek Kitszel 		goto err;
6111948b867SPrzemek Kitszel 	}
6121948b867SPrzemek Kitszel 
6131948b867SPrzemek Kitszel 	if (qbw->num_queues > ICE_MAX_RSS_QS_PER_VF ||
6141948b867SPrzemek Kitszel 	    qbw->num_queues > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
6151948b867SPrzemek Kitszel 		dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n",
6161948b867SPrzemek Kitszel 			vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq));
6171948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6181948b867SPrzemek Kitszel 		goto err;
6191948b867SPrzemek Kitszel 	}
6201948b867SPrzemek Kitszel 
6211948b867SPrzemek Kitszel 	for (i = 0; i < qbw->num_queues; i++) {
6221948b867SPrzemek Kitszel 		if (qbw->cfg[i].shaper.peak != 0 && vf->max_tx_rate != 0 &&
6231948b867SPrzemek Kitszel 		    qbw->cfg[i].shaper.peak > vf->max_tx_rate) {
6241948b867SPrzemek Kitszel 			dev_warn(ice_pf_to_dev(vf->pf), "The maximum queue %d rate limit configuration may not take effect because the maximum TX rate for VF-%d is %d\n",
6251948b867SPrzemek Kitszel 				 qbw->cfg[i].queue_id, vf->vf_id,
6261948b867SPrzemek Kitszel 				 vf->max_tx_rate);
6271948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6281948b867SPrzemek Kitszel 			goto err;
6291948b867SPrzemek Kitszel 		}
6301948b867SPrzemek Kitszel 		if (qbw->cfg[i].shaper.committed != 0 && vf->min_tx_rate != 0 &&
6311948b867SPrzemek Kitszel 		    qbw->cfg[i].shaper.committed < vf->min_tx_rate) {
6321948b867SPrzemek Kitszel 			dev_warn(ice_pf_to_dev(vf->pf), "The minimum queue %d rate limit configuration may not take effect because the minimum TX rate for VF-%d is %d\n",
6331948b867SPrzemek Kitszel 				 qbw->cfg[i].queue_id, vf->vf_id,
6341948b867SPrzemek Kitszel 				 vf->min_tx_rate);
6351948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6361948b867SPrzemek Kitszel 			goto err;
6371948b867SPrzemek Kitszel 		}
6381948b867SPrzemek Kitszel 		if (qbw->cfg[i].queue_id > vf->num_vf_qs) {
6391948b867SPrzemek Kitszel 			dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure invalid queue_id\n",
6401948b867SPrzemek Kitszel 				 vf->vf_id);
6411948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6421948b867SPrzemek Kitszel 			goto err;
6431948b867SPrzemek Kitszel 		}
6441948b867SPrzemek Kitszel 		if (qbw->cfg[i].tc >= ICE_MAX_TRAFFIC_CLASS) {
6451948b867SPrzemek Kitszel 			dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure a traffic class higher than allowed\n",
6461948b867SPrzemek Kitszel 				 vf->vf_id);
6471948b867SPrzemek Kitszel 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6481948b867SPrzemek Kitszel 			goto err;
6491948b867SPrzemek Kitszel 		}
6501948b867SPrzemek Kitszel 	}
6511948b867SPrzemek Kitszel 
6521948b867SPrzemek Kitszel 	for (i = 0; i < qbw->num_queues; i++) {
6531948b867SPrzemek Kitszel 		vf->qs_bw[i].queue_id = qbw->cfg[i].queue_id;
6541948b867SPrzemek Kitszel 		vf->qs_bw[i].peak = qbw->cfg[i].shaper.peak;
6551948b867SPrzemek Kitszel 		vf->qs_bw[i].committed = qbw->cfg[i].shaper.committed;
6561948b867SPrzemek Kitszel 		vf->qs_bw[i].tc = qbw->cfg[i].tc;
6571948b867SPrzemek Kitszel 	}
6581948b867SPrzemek Kitszel 
6591948b867SPrzemek Kitszel 	if (ice_vf_cfg_qs_bw(vf, qbw->num_queues))
6601948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6611948b867SPrzemek Kitszel 
6621948b867SPrzemek Kitszel err:
6631948b867SPrzemek Kitszel 	/* send the response to the VF */
6641948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUEUE_BW,
6651948b867SPrzemek Kitszel 				    v_ret, NULL, 0);
6661948b867SPrzemek Kitszel }
6671948b867SPrzemek Kitszel 
6681948b867SPrzemek Kitszel /**
6691948b867SPrzemek Kitszel  * ice_vc_cfg_q_quanta - Configure per queue quanta
6701948b867SPrzemek Kitszel  * @vf: pointer to the VF info
6711948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer which holds the command descriptor
6721948b867SPrzemek Kitszel  *
6731948b867SPrzemek Kitszel  * Configure VF queues quanta.
6741948b867SPrzemek Kitszel  *
6751948b867SPrzemek Kitszel  * Return: 0 on success or negative error value.
6761948b867SPrzemek Kitszel  */
677c762b0a5SPrzemek Kitszel int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
6781948b867SPrzemek Kitszel {
6791948b867SPrzemek Kitszel 	u16 quanta_prof_id, quanta_size, start_qid, num_queues, end_qid, i;
6801948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
6811948b867SPrzemek Kitszel 	struct virtchnl_quanta_cfg *qquanta =
6821948b867SPrzemek Kitszel 		(struct virtchnl_quanta_cfg *)msg;
6831948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
6841948b867SPrzemek Kitszel 	int ret;
6851948b867SPrzemek Kitszel 
6861948b867SPrzemek Kitszel 	start_qid = qquanta->queue_select.start_queue_id;
6871948b867SPrzemek Kitszel 	num_queues = qquanta->queue_select.num_queues;
6881948b867SPrzemek Kitszel 
6891948b867SPrzemek Kitszel 	if (check_add_overflow(start_qid, num_queues, &end_qid)) {
6901948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6911948b867SPrzemek Kitszel 		goto err;
6921948b867SPrzemek Kitszel 	}
6931948b867SPrzemek Kitszel 
6941948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
6951948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
6961948b867SPrzemek Kitszel 		goto err;
6971948b867SPrzemek Kitszel 	}
6981948b867SPrzemek Kitszel 
6991948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
7001948b867SPrzemek Kitszel 	if (!vsi) {
7011948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
7021948b867SPrzemek Kitszel 		goto err;
7031948b867SPrzemek Kitszel 	}
7041948b867SPrzemek Kitszel 
7051948b867SPrzemek Kitszel 	if (end_qid > ICE_MAX_RSS_QS_PER_VF ||
7061948b867SPrzemek Kitszel 	    end_qid > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
7071948b867SPrzemek Kitszel 		dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n",
7081948b867SPrzemek Kitszel 			vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq));
7091948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
7101948b867SPrzemek Kitszel 		goto err;
7111948b867SPrzemek Kitszel 	}
7121948b867SPrzemek Kitszel 
7131948b867SPrzemek Kitszel 	quanta_size = qquanta->quanta_size;
7141948b867SPrzemek Kitszel 	if (quanta_size > ICE_MAX_QUANTA_SIZE ||
7151948b867SPrzemek Kitszel 	    quanta_size < ICE_MIN_QUANTA_SIZE) {
7161948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
7171948b867SPrzemek Kitszel 		goto err;
7181948b867SPrzemek Kitszel 	}
7191948b867SPrzemek Kitszel 
7201948b867SPrzemek Kitszel 	if (quanta_size % 64) {
7211948b867SPrzemek Kitszel 		dev_err(ice_pf_to_dev(vf->pf), "quanta size should be the product of 64\n");
7221948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
7231948b867SPrzemek Kitszel 		goto err;
7241948b867SPrzemek Kitszel 	}
7251948b867SPrzemek Kitszel 
7261948b867SPrzemek Kitszel 	ret = ice_vf_cfg_q_quanta_profile(vf, quanta_size,
7271948b867SPrzemek Kitszel 					  &quanta_prof_id);
7281948b867SPrzemek Kitszel 	if (ret) {
7291948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
7301948b867SPrzemek Kitszel 		goto err;
7311948b867SPrzemek Kitszel 	}
7321948b867SPrzemek Kitszel 
7331948b867SPrzemek Kitszel 	for (i = start_qid; i < end_qid; i++)
7341948b867SPrzemek Kitszel 		vsi->tx_rings[i]->quanta_prof_id = quanta_prof_id;
7351948b867SPrzemek Kitszel 
7361948b867SPrzemek Kitszel err:
7371948b867SPrzemek Kitszel 	/* send the response to the VF */
7381948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_QUANTA,
7391948b867SPrzemek Kitszel 				     v_ret, NULL, 0);
7401948b867SPrzemek Kitszel }
7411948b867SPrzemek Kitszel 
7421948b867SPrzemek Kitszel /**
7431948b867SPrzemek Kitszel  * ice_vc_cfg_qs_msg
7441948b867SPrzemek Kitszel  * @vf: pointer to the VF info
7451948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer
7461948b867SPrzemek Kitszel  *
7471948b867SPrzemek Kitszel  * called from the VF to configure the Rx/Tx queues
7481948b867SPrzemek Kitszel  */
749c762b0a5SPrzemek Kitszel int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
7501948b867SPrzemek Kitszel {
7511948b867SPrzemek Kitszel 	struct virtchnl_vsi_queue_config_info *qci =
7521948b867SPrzemek Kitszel 	    (struct virtchnl_vsi_queue_config_info *)msg;
7531948b867SPrzemek Kitszel 	struct virtchnl_queue_pair_info *qpi;
7541948b867SPrzemek Kitszel 	struct ice_pf *pf = vf->pf;
7551948b867SPrzemek Kitszel 	struct ice_vsi *vsi;
7561948b867SPrzemek Kitszel 	int i = -1, q_idx;
7571948b867SPrzemek Kitszel 	bool ena_ts;
7581948b867SPrzemek Kitszel 	u8 act_prt;
7591948b867SPrzemek Kitszel 
7601948b867SPrzemek Kitszel 	mutex_lock(&pf->lag_mutex);
7611948b867SPrzemek Kitszel 	act_prt = ice_lag_prepare_vf_reset(pf->lag);
7621948b867SPrzemek Kitszel 
7631948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
7641948b867SPrzemek Kitszel 		goto error_param;
7651948b867SPrzemek Kitszel 
7661948b867SPrzemek Kitszel 	if (!ice_vc_isvalid_vsi_id(vf, qci->vsi_id))
7671948b867SPrzemek Kitszel 		goto error_param;
7681948b867SPrzemek Kitszel 
7691948b867SPrzemek Kitszel 	vsi = ice_get_vf_vsi(vf);
7701948b867SPrzemek Kitszel 	if (!vsi)
7711948b867SPrzemek Kitszel 		goto error_param;
7721948b867SPrzemek Kitszel 
7731948b867SPrzemek Kitszel 	if (qci->num_queue_pairs > ICE_MAX_RSS_QS_PER_VF ||
7741948b867SPrzemek Kitszel 	    qci->num_queue_pairs > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
7751948b867SPrzemek Kitszel 		dev_err(ice_pf_to_dev(pf), "VF-%d requesting more than supported number of queues: %d\n",
7761948b867SPrzemek Kitszel 			vf->vf_id, min_t(u16, vsi->alloc_txq, vsi->alloc_rxq));
7771948b867SPrzemek Kitszel 		goto error_param;
7781948b867SPrzemek Kitszel 	}
7791948b867SPrzemek Kitszel 
7801948b867SPrzemek Kitszel 	for (i = 0; i < qci->num_queue_pairs; i++) {
7811948b867SPrzemek Kitszel 		if (!qci->qpair[i].rxq.crc_disable)
7821948b867SPrzemek Kitszel 			continue;
7831948b867SPrzemek Kitszel 
7841948b867SPrzemek Kitszel 		if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_CRC) ||
7851948b867SPrzemek Kitszel 		    vf->vlan_strip_ena)
7861948b867SPrzemek Kitszel 			goto error_param;
7871948b867SPrzemek Kitszel 	}
7881948b867SPrzemek Kitszel 
7891948b867SPrzemek Kitszel 	for (i = 0; i < qci->num_queue_pairs; i++) {
7901948b867SPrzemek Kitszel 		qpi = &qci->qpair[i];
7911948b867SPrzemek Kitszel 		if (qpi->txq.vsi_id != qci->vsi_id ||
7921948b867SPrzemek Kitszel 		    qpi->rxq.vsi_id != qci->vsi_id ||
7931948b867SPrzemek Kitszel 		    qpi->rxq.queue_id != qpi->txq.queue_id ||
7941948b867SPrzemek Kitszel 		    qpi->txq.headwb_enabled ||
7951948b867SPrzemek Kitszel 		    !ice_vc_isvalid_ring_len(qpi->txq.ring_len) ||
7961948b867SPrzemek Kitszel 		    !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) ||
7971948b867SPrzemek Kitszel 		    !ice_vc_isvalid_q_id(vsi, qpi->txq.queue_id)) {
7981948b867SPrzemek Kitszel 			goto error_param;
7991948b867SPrzemek Kitszel 		}
8001948b867SPrzemek Kitszel 
8011948b867SPrzemek Kitszel 		q_idx = qpi->rxq.queue_id;
8021948b867SPrzemek Kitszel 
8031948b867SPrzemek Kitszel 		/* make sure selected "q_idx" is in valid range of queues
8041948b867SPrzemek Kitszel 		 * for selected "vsi"
8051948b867SPrzemek Kitszel 		 */
8061948b867SPrzemek Kitszel 		if (q_idx >= vsi->alloc_txq || q_idx >= vsi->alloc_rxq) {
8071948b867SPrzemek Kitszel 			goto error_param;
8081948b867SPrzemek Kitszel 		}
8091948b867SPrzemek Kitszel 
8101948b867SPrzemek Kitszel 		/* copy Tx queue info from VF into VSI */
8111948b867SPrzemek Kitszel 		if (qpi->txq.ring_len > 0) {
8121948b867SPrzemek Kitszel 			vsi->tx_rings[q_idx]->dma = qpi->txq.dma_ring_addr;
8131948b867SPrzemek Kitszel 			vsi->tx_rings[q_idx]->count = qpi->txq.ring_len;
8141948b867SPrzemek Kitszel 
8151948b867SPrzemek Kitszel 			/* Disable any existing queue first */
8161948b867SPrzemek Kitszel 			if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx))
8171948b867SPrzemek Kitszel 				goto error_param;
8181948b867SPrzemek Kitszel 
8191948b867SPrzemek Kitszel 			/* Configure a queue with the requested settings */
8201948b867SPrzemek Kitszel 			if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) {
8211948b867SPrzemek Kitszel 				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n",
8221948b867SPrzemek Kitszel 					 vf->vf_id, q_idx);
8231948b867SPrzemek Kitszel 				goto error_param;
8241948b867SPrzemek Kitszel 			}
8251948b867SPrzemek Kitszel 		}
8261948b867SPrzemek Kitszel 
8271948b867SPrzemek Kitszel 		/* copy Rx queue info from VF into VSI */
8281948b867SPrzemek Kitszel 		if (qpi->rxq.ring_len > 0) {
8291948b867SPrzemek Kitszel 			u16 max_frame_size = ice_vc_get_max_frame_size(vf);
8301948b867SPrzemek Kitszel 			struct ice_rx_ring *ring = vsi->rx_rings[q_idx];
8311948b867SPrzemek Kitszel 			u32 rxdid;
8321948b867SPrzemek Kitszel 
8331948b867SPrzemek Kitszel 			ring->dma = qpi->rxq.dma_ring_addr;
8341948b867SPrzemek Kitszel 			ring->count = qpi->rxq.ring_len;
8351948b867SPrzemek Kitszel 
8361948b867SPrzemek Kitszel 			if (qpi->rxq.crc_disable)
8371948b867SPrzemek Kitszel 				ring->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS;
8381948b867SPrzemek Kitszel 			else
8391948b867SPrzemek Kitszel 				ring->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS;
8401948b867SPrzemek Kitszel 
8411948b867SPrzemek Kitszel 			if (qpi->rxq.databuffer_size != 0 &&
8421948b867SPrzemek Kitszel 			    (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
8431948b867SPrzemek Kitszel 			     qpi->rxq.databuffer_size < 1024))
8441948b867SPrzemek Kitszel 				goto error_param;
8451948b867SPrzemek Kitszel 			ring->rx_buf_len = qpi->rxq.databuffer_size;
8461948b867SPrzemek Kitszel 			if (qpi->rxq.max_pkt_size > max_frame_size ||
8471948b867SPrzemek Kitszel 			    qpi->rxq.max_pkt_size < 64)
8481948b867SPrzemek Kitszel 				goto error_param;
8491948b867SPrzemek Kitszel 
8501948b867SPrzemek Kitszel 			ring->max_frame = qpi->rxq.max_pkt_size;
8511948b867SPrzemek Kitszel 			/* add space for the port VLAN since the VF driver is
8521948b867SPrzemek Kitszel 			 * not expected to account for it in the MTU
8531948b867SPrzemek Kitszel 			 * calculation
8541948b867SPrzemek Kitszel 			 */
8551948b867SPrzemek Kitszel 			if (ice_vf_is_port_vlan_ena(vf))
8561948b867SPrzemek Kitszel 				ring->max_frame += VLAN_HLEN;
8571948b867SPrzemek Kitszel 
8581948b867SPrzemek Kitszel 			if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
8591948b867SPrzemek Kitszel 				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",
8601948b867SPrzemek Kitszel 					 vf->vf_id, q_idx);
8611948b867SPrzemek Kitszel 				goto error_param;
8621948b867SPrzemek Kitszel 			}
8631948b867SPrzemek Kitszel 
8641948b867SPrzemek Kitszel 			/* If Rx flex desc is supported, select RXDID for Rx
8651948b867SPrzemek Kitszel 			 * queues. Otherwise, use legacy 32byte descriptor
8661948b867SPrzemek Kitszel 			 * format. Legacy 16byte descriptor is not supported.
8671948b867SPrzemek Kitszel 			 * If this RXDID is selected, return error.
8681948b867SPrzemek Kitszel 			 */
8691948b867SPrzemek Kitszel 			if (vf->driver_caps &
8701948b867SPrzemek Kitszel 			    VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) {
8711948b867SPrzemek Kitszel 				rxdid = qpi->rxq.rxdid;
8721948b867SPrzemek Kitszel 				if (!(BIT(rxdid) & pf->supported_rxdids))
8731948b867SPrzemek Kitszel 					goto error_param;
8741948b867SPrzemek Kitszel 			} else {
8751948b867SPrzemek Kitszel 				rxdid = ICE_RXDID_LEGACY_1;
8761948b867SPrzemek Kitszel 			}
8771948b867SPrzemek Kitszel 
8781948b867SPrzemek Kitszel 			ena_ts = ((vf->driver_caps &
8791948b867SPrzemek Kitszel 				  VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) &&
8801948b867SPrzemek Kitszel 				  (vf->driver_caps & VIRTCHNL_VF_CAP_PTP) &&
8811948b867SPrzemek Kitszel 				  (qpi->rxq.flags & VIRTCHNL_PTP_RX_TSTAMP));
8821948b867SPrzemek Kitszel 
8831948b867SPrzemek Kitszel 			ice_write_qrxflxp_cntxt(&vsi->back->hw,
8841948b867SPrzemek Kitszel 						vsi->rxq_map[q_idx], rxdid,
8851948b867SPrzemek Kitszel 						ICE_RXDID_PRIO, ena_ts);
8861948b867SPrzemek Kitszel 		}
8871948b867SPrzemek Kitszel 	}
8881948b867SPrzemek Kitszel 
8891948b867SPrzemek Kitszel 	ice_lag_complete_vf_reset(pf->lag, act_prt);
8901948b867SPrzemek Kitszel 	mutex_unlock(&pf->lag_mutex);
8911948b867SPrzemek Kitszel 
8921948b867SPrzemek Kitszel 	/* send the response to the VF */
8931948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
8941948b867SPrzemek Kitszel 				     VIRTCHNL_STATUS_SUCCESS, NULL, 0);
8951948b867SPrzemek Kitszel error_param:
8961948b867SPrzemek Kitszel 	/* disable whatever we can */
8971948b867SPrzemek Kitszel 	for (; i >= 0; i--) {
8981948b867SPrzemek Kitszel 		if (ice_vsi_ctrl_one_rx_ring(vsi, false, i, true))
8991948b867SPrzemek Kitszel 			dev_err(ice_pf_to_dev(pf), "VF-%d could not disable RX queue %d\n",
9001948b867SPrzemek Kitszel 				vf->vf_id, i);
9011948b867SPrzemek Kitszel 		if (ice_vf_vsi_dis_single_txq(vf, vsi, i))
9021948b867SPrzemek Kitszel 			dev_err(ice_pf_to_dev(pf), "VF-%d could not disable TX queue %d\n",
9031948b867SPrzemek Kitszel 				vf->vf_id, i);
9041948b867SPrzemek Kitszel 	}
9051948b867SPrzemek Kitszel 
9061948b867SPrzemek Kitszel 	ice_lag_complete_vf_reset(pf->lag, act_prt);
9071948b867SPrzemek Kitszel 	mutex_unlock(&pf->lag_mutex);
9081948b867SPrzemek Kitszel 
9091948b867SPrzemek Kitszel 	/* send the response to the VF */
9101948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
9111948b867SPrzemek Kitszel 				     VIRTCHNL_STATUS_ERR_PARAM, NULL, 0);
9121948b867SPrzemek Kitszel }
9131948b867SPrzemek Kitszel 
9141948b867SPrzemek Kitszel /**
9151948b867SPrzemek Kitszel  * ice_vc_request_qs_msg
9161948b867SPrzemek Kitszel  * @vf: pointer to the VF info
9171948b867SPrzemek Kitszel  * @msg: pointer to the msg buffer
9181948b867SPrzemek Kitszel  *
9191948b867SPrzemek Kitszel  * VFs get a default number of queues but can use this message to request a
9201948b867SPrzemek Kitszel  * different number. If the request is successful, PF will reset the VF and
9211948b867SPrzemek Kitszel  * return 0. If unsuccessful, PF will send message informing VF of number of
9221948b867SPrzemek Kitszel  * available queue pairs via virtchnl message response to VF.
9231948b867SPrzemek Kitszel  */
924c762b0a5SPrzemek Kitszel int ice_vc_request_qs_msg(struct ice_vf *vf, u8 *msg)
9251948b867SPrzemek Kitszel {
9261948b867SPrzemek Kitszel 	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
9271948b867SPrzemek Kitszel 	struct virtchnl_vf_res_request *vfres =
9281948b867SPrzemek Kitszel 		(struct virtchnl_vf_res_request *)msg;
9291948b867SPrzemek Kitszel 	u16 req_queues = vfres->num_queue_pairs;
9301948b867SPrzemek Kitszel 	struct ice_pf *pf = vf->pf;
9311948b867SPrzemek Kitszel 	u16 max_allowed_vf_queues;
9321948b867SPrzemek Kitszel 	u16 tx_rx_queue_left;
9331948b867SPrzemek Kitszel 	struct device *dev;
9341948b867SPrzemek Kitszel 	u16 cur_queues;
9351948b867SPrzemek Kitszel 
9361948b867SPrzemek Kitszel 	dev = ice_pf_to_dev(pf);
9371948b867SPrzemek Kitszel 	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
9381948b867SPrzemek Kitszel 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
9391948b867SPrzemek Kitszel 		goto error_param;
9401948b867SPrzemek Kitszel 	}
9411948b867SPrzemek Kitszel 
9421948b867SPrzemek Kitszel 	cur_queues = vf->num_vf_qs;
9431948b867SPrzemek Kitszel 	tx_rx_queue_left = min_t(u16, ice_get_avail_txq_count(pf),
9441948b867SPrzemek Kitszel 				 ice_get_avail_rxq_count(pf));
9451948b867SPrzemek Kitszel 	max_allowed_vf_queues = tx_rx_queue_left + cur_queues;
9461948b867SPrzemek Kitszel 	if (!req_queues) {
9471948b867SPrzemek Kitszel 		dev_err(dev, "VF %d tried to request 0 queues. Ignoring.\n",
9481948b867SPrzemek Kitszel 			vf->vf_id);
9491948b867SPrzemek Kitszel 	} else if (req_queues > ICE_MAX_RSS_QS_PER_VF) {
9501948b867SPrzemek Kitszel 		dev_err(dev, "VF %d tried to request more than %d queues.\n",
9511948b867SPrzemek Kitszel 			vf->vf_id, ICE_MAX_RSS_QS_PER_VF);
9521948b867SPrzemek Kitszel 		vfres->num_queue_pairs = ICE_MAX_RSS_QS_PER_VF;
9531948b867SPrzemek Kitszel 	} else if (req_queues > cur_queues &&
9541948b867SPrzemek Kitszel 		   req_queues - cur_queues > tx_rx_queue_left) {
9551948b867SPrzemek Kitszel 		dev_warn(dev, "VF %d requested %u more queues, but only %u left.\n",
9561948b867SPrzemek Kitszel 			 vf->vf_id, req_queues - cur_queues, tx_rx_queue_left);
9571948b867SPrzemek Kitszel 		vfres->num_queue_pairs = min_t(u16, max_allowed_vf_queues,
9581948b867SPrzemek Kitszel 					       ICE_MAX_RSS_QS_PER_VF);
9591948b867SPrzemek Kitszel 	} else {
9601948b867SPrzemek Kitszel 		/* request is successful, then reset VF */
9611948b867SPrzemek Kitszel 		vf->num_req_qs = req_queues;
9621948b867SPrzemek Kitszel 		ice_reset_vf(vf, ICE_VF_RESET_NOTIFY);
9631948b867SPrzemek Kitszel 		dev_info(dev, "VF %d granted request of %u queues.\n",
9641948b867SPrzemek Kitszel 			 vf->vf_id, req_queues);
9651948b867SPrzemek Kitszel 		return 0;
9661948b867SPrzemek Kitszel 	}
9671948b867SPrzemek Kitszel 
9681948b867SPrzemek Kitszel error_param:
9691948b867SPrzemek Kitszel 	/* send the response to the VF */
9701948b867SPrzemek Kitszel 	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES,
9711948b867SPrzemek Kitszel 				     v_ret, (u8 *)vfres, sizeof(*vfres));
9721948b867SPrzemek Kitszel }
9731948b867SPrzemek Kitszel 
974