summaryrefslogtreecommitdiffstats
path: root/drivers/net/i40e/i40e_pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/i40e/i40e_pf.c')
-rw-r--r--drivers/net/i40e/i40e_pf.c178
1 files changed, 132 insertions, 46 deletions
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 94bb0cfd..dd3962d3 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -1,34 +1,5 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2017 Intel Corporation
*/
#include <sys/queue.h>
@@ -43,7 +14,7 @@
#include <rte_string_fns.h>
#include <rte_pci.h>
#include <rte_ether.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
@@ -273,19 +244,23 @@ i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf,
}
static void
-i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, bool b_op)
+i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, uint8_t *msg,
+ bool b_op)
{
struct virtchnl_version_info info;
- /* Respond like a Linux PF host in order to support both DPDK VF and
- * Linux VF driver. The expense is original DPDK host specific feature
+ /* VF and PF drivers need to follow the Virtchnl definition, No matter
+ * it's DPDK or other kernel drivers.
+ * The original DPDK host specific feature
* like CFG_VLAN_PVID and CONFIG_VSI_QUEUES_EXT will not available.
- *
- * DPDK VF also can't identify host driver by version number returned.
- * It always assume talking with Linux PF.
*/
+
info.major = VIRTCHNL_VERSION_MAJOR;
- info.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS;
+ vf->version = *(struct virtchnl_version_info *)msg;
+ if (VF_IS_V10(&vf->version))
+ info.minor = VIRTCHNL_VERSION_MINOR_NO_VF_CAPS;
+ else
+ info.minor = VIRTCHNL_VERSION_MINOR;
if (b_op)
i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_VERSION,
@@ -309,11 +284,13 @@ i40e_pf_host_process_cmd_reset_vf(struct i40e_pf_vf *vf)
}
static int
-i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, bool b_op)
+i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, uint8_t *msg,
+ bool b_op)
{
struct virtchnl_vf_resource *vf_res = NULL;
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
uint32_t len = 0;
+ uint64_t default_hena = I40E_RSS_HENA_ALL;
int ret = I40E_SUCCESS;
if (!b_op) {
@@ -337,11 +314,35 @@ i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, bool b_op)
goto send_msg;
}
- vf_res->vf_offload_flags = VIRTCHNL_VF_OFFLOAD_L2 |
- VIRTCHNL_VF_OFFLOAD_VLAN;
+ if (VF_IS_V10(&vf->version)) /* doesn't support offload negotiate */
+ vf->request_caps = VIRTCHNL_VF_OFFLOAD_L2 |
+ VIRTCHNL_VF_OFFLOAD_VLAN;
+ else
+ vf->request_caps = *(uint32_t *)msg;
+
+ /* enable all RSS by default,
+ * doesn't support hena setting by virtchnnl yet.
+ */
+ if (vf->request_caps & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+ I40E_WRITE_REG(hw, I40E_VFQF_HENA1(0, vf->vf_idx),
+ (uint32_t)default_hena);
+ I40E_WRITE_REG(hw, I40E_VFQF_HENA1(1, vf->vf_idx),
+ (uint32_t)(default_hena >> 32));
+ I40E_WRITE_FLUSH(hw);
+ }
+
+ vf_res->vf_cap_flags = vf->request_caps &
+ I40E_VIRTCHNL_OFFLOAD_CAPS;
+ /* For X722, it supports write back on ITR
+ * without binding queue to interrupt vector.
+ */
+ if (hw->mac.type == I40E_MAC_X722)
+ vf_res->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
vf_res->max_vectors = hw->func_caps.num_msix_vectors_vf;
vf_res->num_queue_pairs = vf->vsi->nb_qps;
vf_res->num_vsis = I40E_DEFAULT_VF_VSI_NUM;
+ vf_res->rss_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 4;
+ vf_res->rss_lut_size = (I40E_VFQF_HLUT1_MAX_INDEX + 1) * 4;
/* Change below setting if PF host can support more VSIs for VF */
vf_res->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;
@@ -1090,6 +1091,84 @@ i40e_pf_host_process_cmd_disable_vlan_strip(struct i40e_pf_vf *vf, bool b_op)
return ret;
}
+static int
+i40e_pf_host_process_cmd_set_rss_lut(struct i40e_pf_vf *vf,
+ uint8_t *msg,
+ uint16_t msglen,
+ bool b_op)
+{
+ struct virtchnl_rss_lut *rss_lut = (struct virtchnl_rss_lut *)msg;
+ uint16_t valid_len;
+ int ret = I40E_SUCCESS;
+
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ VIRTCHNL_OP_CONFIG_RSS_LUT,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
+ if (!msg || msglen <= sizeof(struct virtchnl_rss_lut)) {
+ PMD_DRV_LOG(ERR, "set_rss_lut argument too short");
+ ret = I40E_ERR_PARAM;
+ goto send_msg;
+ }
+ valid_len = sizeof(struct virtchnl_rss_lut) + rss_lut->lut_entries - 1;
+ if (msglen < valid_len) {
+ PMD_DRV_LOG(ERR, "set_rss_lut length mismatch");
+ ret = I40E_ERR_PARAM;
+ goto send_msg;
+ }
+
+ ret = i40e_set_rss_lut(vf->vsi, rss_lut->lut, rss_lut->lut_entries);
+
+send_msg:
+ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT,
+ ret, NULL, 0);
+
+ return ret;
+}
+
+static int
+i40e_pf_host_process_cmd_set_rss_key(struct i40e_pf_vf *vf,
+ uint8_t *msg,
+ uint16_t msglen,
+ bool b_op)
+{
+ struct virtchnl_rss_key *rss_key = (struct virtchnl_rss_key *)msg;
+ uint16_t valid_len;
+ int ret = I40E_SUCCESS;
+
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ VIRTCHNL_OP_DEL_VLAN,
+ VIRTCHNL_OP_CONFIG_RSS_KEY, NULL, 0);
+ return ret;
+ }
+
+ if (!msg || msglen <= sizeof(struct virtchnl_rss_key)) {
+ PMD_DRV_LOG(ERR, "set_rss_key argument too short");
+ ret = I40E_ERR_PARAM;
+ goto send_msg;
+ }
+ valid_len = sizeof(struct virtchnl_rss_key) + rss_key->key_len - 1;
+ if (msglen < valid_len) {
+ PMD_DRV_LOG(ERR, "set_rss_key length mismatch");
+ ret = I40E_ERR_PARAM;
+ goto send_msg;
+ }
+
+ ret = i40e_set_rss_key(vf->vsi, rss_key->key, rss_key->key_len);
+
+send_msg:
+ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_KEY,
+ ret, NULL, 0);
+
+ return ret;
+}
+
void
i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf)
{
@@ -1185,8 +1264,7 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
* do nothing and send not_supported to VF. As PF must send a response
* to VF and ACK/NACK is not defined.
*/
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX,
- NULL, &ret_param);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &ret_param);
if (ret_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) {
PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!",
opcode);
@@ -1196,7 +1274,7 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
switch (opcode) {
case VIRTCHNL_OP_VERSION:
PMD_DRV_LOG(INFO, "OP_VERSION received");
- i40e_pf_host_process_cmd_version(vf, b_op);
+ i40e_pf_host_process_cmd_version(vf, msg, b_op);
break;
case VIRTCHNL_OP_RESET_VF:
PMD_DRV_LOG(INFO, "OP_RESET_VF received");
@@ -1204,7 +1282,7 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
break;
case VIRTCHNL_OP_GET_VF_RESOURCES:
PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received");
- i40e_pf_host_process_cmd_get_vf_resource(vf, b_op);
+ i40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op);
break;
case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received");
@@ -1265,6 +1343,14 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
PMD_DRV_LOG(INFO, "OP_DISABLE_VLAN_STRIPPING received");
i40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op);
break;
+ case VIRTCHNL_OP_CONFIG_RSS_LUT:
+ PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_LUT received");
+ i40e_pf_host_process_cmd_set_rss_lut(vf, msg, msglen, b_op);
+ break;
+ case VIRTCHNL_OP_CONFIG_RSS_KEY:
+ PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_KEY received");
+ i40e_pf_host_process_cmd_set_rss_key(vf, msg, msglen, b_op);
+ break;
/* Don't add command supported below, which will
* return an error code.
*/