Commit 2a86e210 authored by Jacob Keller's avatar Jacob Keller Committed by Tony Nguyen
Browse files

iavf: add support for negotiating flexible RXDID format



Enable support for VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC, to enable the VF
driver the ability to determine what Rx descriptor formats are
available. This requires sending an additional message during
initialization and reset, the VIRTCHNL_OP_GET_SUPPORTED_RXDIDS. This
operation requests the supported Rx descriptor IDs available from the
PF.

This is treated the same way that VLAN V2 capabilities are handled. Add
a new set of extended capability flags, used to process send and receipt
of the VIRTCHNL_OP_GET_SUPPORTED_RXDIDS message.

This ensures we finish negotiating for the supported descriptor formats
prior to beginning configuration of receive queues.

This change stores the supported format bitmap into the iavf_adapter
structure. Additionally, if VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC is enabled
by the PF, we need to make sure that the Rx queue configuration
specifies the format.

Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Co-developed-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 6a88c797
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ struct iavf_adapter {
	/* Lock to protect accesses to MAC and VLAN lists */
	spinlock_t mac_vlan_list_lock;
	char misc_vector_name[IFNAMSIZ + 9];
	u8 rxdid;
	int num_active_queues;
	int num_req_queues;

@@ -343,6 +344,14 @@ struct iavf_adapter {
#define IAVF_FLAG_AQ_CONFIGURE_QUEUES_BW		BIT_ULL(39)
#define IAVF_FLAG_AQ_CFG_QUEUES_QUANTA_SIZE		BIT_ULL(40)
#define IAVF_FLAG_AQ_GET_QOS_CAPS			BIT_ULL(41)
#define IAVF_FLAG_AQ_GET_SUPPORTED_RXDIDS		BIT_ULL(42)

	/* AQ messages that must be sent after IAVF_FLAG_AQ_GET_CONFIG, in
	 * order to negotiated extended capabilities.
	 */
#define IAVF_FLAG_AQ_EXTENDED_CAPS			\
	(IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS |	\
	 IAVF_FLAG_AQ_GET_SUPPORTED_RXDIDS)

	/* flags for processing extended capability messages during
	 * __IAVF_INIT_EXTENDED_CAPS. Each capability exchange requires
@@ -354,10 +363,14 @@ struct iavf_adapter {
	u64 extended_caps;
#define IAVF_EXTENDED_CAP_SEND_VLAN_V2			BIT_ULL(0)
#define IAVF_EXTENDED_CAP_RECV_VLAN_V2			BIT_ULL(1)
#define IAVF_EXTENDED_CAP_SEND_RXDID			BIT_ULL(2)
#define IAVF_EXTENDED_CAP_RECV_RXDID			BIT_ULL(3)

#define IAVF_EXTENDED_CAPS				\
	(IAVF_EXTENDED_CAP_SEND_VLAN_V2 |		\
	 IAVF_EXTENDED_CAP_RECV_VLAN_V2)
	 IAVF_EXTENDED_CAP_RECV_VLAN_V2 |		\
	 IAVF_EXTENDED_CAP_SEND_RXDID |			\
	 IAVF_EXTENDED_CAP_RECV_RXDID)

	/* Lock to prevent possible clobbering of
	 * current_netdev_promisc_flags
@@ -417,12 +430,15 @@ struct iavf_adapter {
			     VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF)
#define QOS_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
			 VIRTCHNL_VF_OFFLOAD_QOS)
#define IAVF_RXDID_ALLOWED(a)						\
	((a)->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC)
	struct virtchnl_vf_resource *vf_res; /* incl. all VSIs */
	struct virtchnl_vsi_resource *vsi_res; /* our LAN VSI */
	struct virtchnl_version_info pf_version;
#define PF_IS_V11(_a) (((_a)->pf_version.major == 1) && \
		       ((_a)->pf_version.minor == 1))
	struct virtchnl_vlan_caps vlan_v2_caps;
	u64 supp_rxdids;
	u16 msg_enable;
	struct iavf_eth_stats current_stats;
	struct virtchnl_qos_cap_list *qos_caps;
@@ -555,6 +571,8 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter);
int iavf_get_vf_config(struct iavf_adapter *adapter);
int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
int iavf_send_vf_supported_rxdids_msg(struct iavf_adapter *adapter);
int iavf_get_vf_supported_rxdids(struct iavf_adapter *adapter);
void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
+115 −8
Original line number Diff line number Diff line
@@ -709,6 +709,38 @@ static void iavf_configure_tx(struct iavf_adapter *adapter)
		adapter->tx_rings[i].tail = hw->hw_addr + IAVF_QTX_TAIL1(i);
}

/**
 * iavf_select_rx_desc_format - Select Rx descriptor format
 * @adapter: adapter private structure
 *
 * Select what Rx descriptor format based on availability and enabled
 * features.
 *
 * Return: the desired RXDID to select for a given Rx queue, as defined by
 *         enum virtchnl_rxdid_format.
 */
static u8 iavf_select_rx_desc_format(const struct iavf_adapter *adapter)
{
	u64 rxdids = adapter->supp_rxdids;

	/* If we did not negotiate VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC, we must
	 * stick with the default value of the legacy 32 byte format.
	 */
	if (!IAVF_RXDID_ALLOWED(adapter))
		return VIRTCHNL_RXDID_1_32B_BASE;

	/* Warn if the PF does not list support for the default legacy
	 * descriptor format. This shouldn't happen, as this is the format
	 * used if VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC is not supported. It is
	 * likely caused by a bug in the PF implementation failing to indicate
	 * support for the format.
	 */
	if (!(rxdids & VIRTCHNL_RXDID_1_32B_BASE_M))
		netdev_warn(adapter->netdev, "PF does not list support for default Rx descriptor format\n");

	return VIRTCHNL_RXDID_1_32B_BASE;
}

/**
 * iavf_configure_rx - Configure Receive Unit after Reset
 * @adapter: board private structure
@@ -719,8 +751,12 @@ static void iavf_configure_rx(struct iavf_adapter *adapter)
{
	struct iavf_hw *hw = &adapter->hw;

	for (u32 i = 0; i < adapter->num_active_queues; i++)
	adapter->rxdid = iavf_select_rx_desc_format(adapter);

	for (u32 i = 0; i < adapter->num_active_queues; i++) {
		adapter->rx_rings[i].tail = hw->hw_addr + IAVF_QRX_TAIL1(i);
		adapter->rx_rings[i].rxdid = adapter->rxdid;
	}
}

/**
@@ -2071,6 +2107,8 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
		return iavf_send_vf_config_msg(adapter);
	if (adapter->aq_required & IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS)
		return iavf_send_vf_offload_vlan_v2_msg(adapter);
	if (adapter->aq_required & IAVF_FLAG_AQ_GET_SUPPORTED_RXDIDS)
		return iavf_send_vf_supported_rxdids_msg(adapter);
	if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_QUEUES) {
		iavf_disable_queues(adapter);
		return 0;
@@ -2599,6 +2637,63 @@ static void iavf_init_recv_offload_vlan_v2_caps(struct iavf_adapter *adapter)
	iavf_change_state(adapter, __IAVF_INIT_FAILED);
}

/**
 * iavf_init_send_supported_rxdids - part of querying for supported RXDID
 * formats
 * @adapter: board private structure
 *
 * Function processes send of the request for supported RXDIDs to the PF.
 * Must clear IAVF_EXTENDED_CAP_RECV_RXDID if the message is not sent, e.g.
 * due to the PF not negotiating VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC.
 */
static void iavf_init_send_supported_rxdids(struct iavf_adapter *adapter)
{
	int ret;

	ret = iavf_send_vf_supported_rxdids_msg(adapter);
	if (ret == -EOPNOTSUPP) {
		/* PF does not support VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC. In this
		 * case, we did not send the capability exchange message and
		 * do not expect a response.
		 */
		adapter->extended_caps &= ~IAVF_EXTENDED_CAP_RECV_RXDID;
	}

	/* We sent the message, so move on to the next step */
	adapter->extended_caps &= ~IAVF_EXTENDED_CAP_SEND_RXDID;
}

/**
 * iavf_init_recv_supported_rxdids - part of querying for supported RXDID
 * formats
 * @adapter: board private structure
 *
 * Function processes receipt of the supported RXDIDs message from the PF.
 **/
static void iavf_init_recv_supported_rxdids(struct iavf_adapter *adapter)
{
	int ret;

	memset(&adapter->supp_rxdids, 0, sizeof(adapter->supp_rxdids));

	ret = iavf_get_vf_supported_rxdids(adapter);
	if (ret)
		goto err;

	/* We've processed the PF response to the
	 * VIRTCHNL_OP_GET_SUPPORTED_RXDIDS message we sent previously.
	 */
	adapter->extended_caps &= ~IAVF_EXTENDED_CAP_RECV_RXDID;
	return;

err:
	/* We didn't receive a reply. Make sure we try sending again when
	 * __IAVF_INIT_FAILED attempts to recover.
	 */
	adapter->extended_caps |= IAVF_EXTENDED_CAP_SEND_RXDID;
	iavf_change_state(adapter, __IAVF_INIT_FAILED);
}

/**
 * iavf_init_process_extended_caps - Part of driver startup
 * @adapter: board private structure
@@ -2623,6 +2718,15 @@ static void iavf_init_process_extended_caps(struct iavf_adapter *adapter)
		return;
	}

	/* Process capability exchange for RXDID formats */
	if (adapter->extended_caps & IAVF_EXTENDED_CAP_SEND_RXDID) {
		iavf_init_send_supported_rxdids(adapter);
		return;
	} else if (adapter->extended_caps & IAVF_EXTENDED_CAP_RECV_RXDID) {
		iavf_init_recv_supported_rxdids(adapter);
		return;
	}

	/* When we reach here, no further extended capabilities exchanges are
	 * necessary, so we finally transition into __IAVF_INIT_CONFIG_ADAPTER
	 */
@@ -3139,15 +3243,18 @@ static void iavf_reset_task(struct work_struct *work)
	}

	adapter->aq_required |= IAVF_FLAG_AQ_GET_CONFIG;
	/* always set since VIRTCHNL_OP_GET_VF_RESOURCES has not been
	 * sent/received yet, so VLAN_V2_ALLOWED() cannot is not reliable here,
	 * however the VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS won't be sent until
	 * VIRTCHNL_OP_GET_VF_RESOURCES and VIRTCHNL_VF_OFFLOAD_VLAN_V2 have
	 * been successfully sent and negotiated
	 */
	adapter->aq_required |= IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS;
	adapter->aq_required |= IAVF_FLAG_AQ_MAP_VECTORS;

	/* Certain capabilities require an extended negotiation process using
	 * extra messages that must be processed after getting the VF
	 * configuration. The related checks such as VLAN_V2_ALLOWED() are not
	 * reliable here, since the configuration has not yet been negotiated.
	 *
	 * Always set these flags, since them related VIRTCHNL messages won't
	 * be sent until after VIRTCHNL_OP_GET_VF_RESOURCES.
	 */
	adapter->aq_required |= IAVF_FLAG_AQ_EXTENDED_CAPS;

	spin_lock_bh(&adapter->mac_vlan_list_lock);

	/* Delete filter for the current MAC address, it could have
+2 −0
Original line number Diff line number Diff line
@@ -262,6 +262,8 @@ struct iavf_ring {
	u16 next_to_use;
	u16 next_to_clean;

	u16 rxdid;		/* Rx descriptor format */

	u16 flags;
#define IAVF_TXR_FLAGS_WB_ON_ITR		BIT(0)
#define IAVF_TXR_FLAGS_ARM_WB			BIT(1)
+40 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
	       VIRTCHNL_VF_OFFLOAD_ENCAP |
	       VIRTCHNL_VF_OFFLOAD_TC_U32 |
	       VIRTCHNL_VF_OFFLOAD_VLAN_V2 |
	       VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
	       VIRTCHNL_VF_OFFLOAD_CRC |
	       VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
	       VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
@@ -177,6 +178,19 @@ int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter)
				NULL, 0);
}

int iavf_send_vf_supported_rxdids_msg(struct iavf_adapter *adapter)
{
	adapter->aq_required &= ~IAVF_FLAG_AQ_GET_SUPPORTED_RXDIDS;

	if (!IAVF_RXDID_ALLOWED(adapter))
		return -EOPNOTSUPP;

	adapter->current_op = VIRTCHNL_OP_GET_SUPPORTED_RXDIDS;

	return iavf_send_pf_msg(adapter, VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
				NULL, 0);
}

/**
 * iavf_validate_num_queues
 * @adapter: adapter structure
@@ -263,6 +277,23 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
	return err;
}

int iavf_get_vf_supported_rxdids(struct iavf_adapter *adapter)
{
	struct iavf_arq_event_info event;
	u64 rxdids;
	int err;

	event.msg_buf = (u8 *)&rxdids;
	event.buf_len = sizeof(rxdids);

	err = iavf_poll_virtchnl_msg(&adapter->hw, &event,
				     VIRTCHNL_OP_GET_SUPPORTED_RXDIDS);
	if (!err)
		adapter->supp_rxdids = rxdids;

	return err;
}

/**
 * iavf_configure_queues
 * @adapter: adapter structure
@@ -309,6 +340,8 @@ void iavf_configure_queues(struct iavf_adapter *adapter)
		vqpi->rxq.dma_ring_addr = adapter->rx_rings[i].dma;
		vqpi->rxq.max_pkt_size = max_frame;
		vqpi->rxq.databuffer_size = adapter->rx_rings[i].rx_buf_len;
		if (IAVF_RXDID_ALLOWED(adapter))
			vqpi->rxq.rxdid = adapter->rxdid;
		if (CRC_OFFLOAD_ALLOWED(adapter))
			vqpi->rxq.crc_disable = !!(adapter->netdev->features &
						   NETIF_F_RXFCS);
@@ -2508,6 +2541,13 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
		adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER |
			aq_required;
		}
		break;
	case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS:
		if (msglen != sizeof(u64))
			return;

		adapter->supp_rxdids = *(u64 *)msg;

		break;
	case VIRTCHNL_OP_ENABLE_QUEUES:
		/* enable transmits */
+2 −2
Original line number Diff line number Diff line
@@ -3040,8 +3040,8 @@ static int ice_vc_set_rss_hena(struct ice_vf *vf, u8 *msg)
static int ice_vc_query_rxdid(struct ice_vf *vf)
{
	enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
	struct virtchnl_supported_rxdids rxdid = {};
	struct ice_pf *pf = vf->pf;
	u64 rxdid;

	if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
@@ -3053,7 +3053,7 @@ static int ice_vc_query_rxdid(struct ice_vf *vf)
		goto err;
	}

	rxdid.supported_rxdids = pf->supported_rxdids;
	rxdid = pf->supported_rxdids;

err:
	return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_SUPPORTED_RXDIDS,
Loading